@seafile/sdoc-editor 1.0.27 → 1.0.29

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 (23) hide show
  1. package/dist/basic-sdk/comment/components/global-comment/index.js +1 -1
  2. package/dist/basic-sdk/comment/utils/index.js +1 -1
  3. package/dist/basic-sdk/editor/comment-article.js +1 -1
  4. package/dist/basic-sdk/extension/constants/menus-config.js +3 -3
  5. package/dist/basic-sdk/extension/core/queries/index.js +7 -0
  6. package/dist/basic-sdk/extension/core/utils/index.js +4 -3
  7. package/dist/basic-sdk/extension/plugins/callout/helper.js +17 -0
  8. package/dist/basic-sdk/extension/plugins/callout/plugin.js +1 -2
  9. package/dist/basic-sdk/extension/plugins/callout/render-elem/index.js +7 -30
  10. package/dist/basic-sdk/extension/plugins/check-list/helpers.js +33 -4
  11. package/dist/basic-sdk/extension/plugins/code-block/hover-menu/index.js +1 -1
  12. package/dist/basic-sdk/extension/plugins/link/helpers.js +16 -0
  13. package/dist/basic-sdk/{assets/css/textlink-hovermenu.css → extension/plugins/link/hover/index.css} +1 -1
  14. package/dist/basic-sdk/extension/plugins/link/hover/index.js +1 -1
  15. package/dist/basic-sdk/extension/plugins/link/render-elem.js +39 -18
  16. package/dist/basic-sdk/extension/plugins/list/plugin/shortcut.js +1 -1
  17. package/dist/basic-sdk/extension/plugins/mention/render-elem/participant-popover.js +1 -1
  18. package/dist/basic-sdk/extension/plugins/table/menu/vertical-align-popover/style.css +0 -1
  19. package/dist/basic-sdk/extension/toolbar/side-toolbar/helpers.js +8 -1
  20. package/dist/basic-sdk/extension/toolbar/side-toolbar/transform-menus.js +7 -1
  21. package/package.json +1 -1
  22. package/public/locales/en/sdoc-editor.json +1 -1
  23. package/public/locales/ru/sdoc-editor.json +1 -1
@@ -1,5 +1,5 @@
1
1
  import _objectSpread from "@babel/runtime/helpers/esm/objectSpread2";
2
- import React, { useCallback, useEffect, useLayoutEffect, useRef, useState } from 'react';
2
+ import React, { useCallback, useEffect, useRef, useState } from 'react';
3
3
  import dayjs from 'dayjs';
4
4
  import EventBus from '../../../utils/event-bus';
5
5
  import useCommentList from '../../hooks/comment-hooks/use-comment-list';
@@ -31,7 +31,7 @@ export const searchCollaborators = (collaborators, searchValue) => {
31
31
  };
32
32
 
33
33
  // Mailto, file, tel, callto, sms, cid, xmpp, etc. are not support
34
- const ALLOWED_URL_REG = /((http|https):\/\/[-A-Za-z0-9+&@#/%?=~_|!:,.;]+[-A-Za-z0-9+&@#/%=~_|])/g;
34
+ // const ALLOWED_URL_REG = /((http|https):\/\/[-A-Za-z0-9+&@#/%?=~_|!:,.;]+[-A-Za-z0-9+&@#/%=~_|])/g;
35
35
  // export const textToHtml = (text) => {
36
36
  // if (!text) return '';
37
37
  // return text.replace(ALLOWED_URL_REG, '<a href="$1" target="_blank" class=' + COMMENT_URL_CLASSNAME + '>$1</a>');
@@ -1,7 +1,7 @@
1
1
  import _objectSpread from "@babel/runtime/helpers/esm/objectSpread2";
2
2
  import React, { useCallback, useMemo } from 'react';
3
3
  import { Editable, ReactEditor, Slate } from '@seafile/slate-react';
4
- import { Editor, Node, Range } from '@seafile/slate';
4
+ import { Editor, Node } from '@seafile/slate';
5
5
  import isHotkey from 'is-hotkey';
6
6
  import scrollIntoView from 'scroll-into-view-if-needed';
7
7
  import { renderLeaf } from '../extension';
@@ -64,7 +64,7 @@ export const MENUS_CONFIG_MAP = {
64
64
  [CHECK_LIST_ITEM]: {
65
65
  id: CHECK_LIST_ITEM,
66
66
  iconClass: 'sdocfont sdoc-check-square',
67
- text: 'Check_list_item'
67
+ text: 'Check_list'
68
68
  },
69
69
  [CODE_BLOCK]: {
70
70
  id: CODE_BLOCK,
@@ -255,7 +255,7 @@ export const SIDE_TRANSFORM_MENUS_CONFIG = [{
255
255
  id: CHECK_LIST_ITEM,
256
256
  iconClass: 'sdocfont sdoc-check-square',
257
257
  type: CHECK_LIST_ITEM,
258
- text: 'Check_list_item'
258
+ text: 'Check_list'
259
259
  }, {
260
260
  id: BLOCKQUOTE,
261
261
  iconClass: 'sdocfont sdoc-quote1',
@@ -315,7 +315,7 @@ export const SIDE_INSERT_MENUS_CONFIG = {
315
315
  id: '',
316
316
  iconClass: 'sdocfont sdoc-check-square',
317
317
  type: CHECK_LIST_ITEM,
318
- text: 'Check_list_item'
318
+ text: 'Check_list'
319
319
  },
320
320
  [PARAGRAPH]: {
321
321
  id: PARAGRAPH,
@@ -451,4 +451,11 @@ export const isCurrentLineEmpty = editor => {
451
451
  };
452
452
  export const isCurrentLineHasText = node => {
453
453
  return Node.string(node).trim() !== '';
454
+ };
455
+ export const isMultiLevelList = listNode => {
456
+ const {
457
+ children
458
+ } = listNode || {};
459
+ let isMultiLevel = (children === null || children === void 0 ? void 0 : children.find(item => (item === null || item === void 0 ? void 0 : item.children.length) > 1)) ? true : false;
460
+ return isMultiLevel;
454
461
  };
@@ -17,10 +17,10 @@ export const match = (node, path, predicate) => {
17
17
  }
18
18
  return predicate(node, path);
19
19
  };
20
- export const generateDefaultText = () => {
20
+ export const generateDefaultText = text => {
21
21
  return {
22
22
  id: slugid.nice(),
23
- text: ''
23
+ text: text || ''
24
24
  };
25
25
  };
26
26
  export const generateDefaultParagraph = () => {
@@ -32,11 +32,12 @@ export const generateDefaultParagraph = () => {
32
32
  };
33
33
  export const generateEmptyElement = function (type) {
34
34
  let props = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
35
+ let text = arguments.length > 2 ? arguments[2] : undefined;
35
36
  return _objectSpread(_objectSpread({
36
37
  id: slugid.nice(),
37
38
  type
38
39
  }, props), {}, {
39
- children: [generateDefaultText()]
40
+ children: [generateDefaultText(text)]
40
41
  });
41
42
  };
42
43
  export function Placeholder(props) {
@@ -2,6 +2,7 @@ import { Editor, Node, Path, Transforms } from '@seafile/slate';
2
2
  import { CALL_OUT, PARAGRAPH } from '../../constants/element-type';
3
3
  import { focusEditor, generateEmptyElement, getSelectedElems, isRangeAcrossBlocks } from '../../core';
4
4
  import { CALLOUT_ALLOWED_INSIDE_TYPES, CALLOUT_COLOR_MAP } from './constant';
5
+ import { DOCUMENT_PLUGIN_EDITOR } from '../../../constants';
5
6
  export const isMenuActive = editor => {
6
7
  const {
7
8
  selection
@@ -124,4 +125,20 @@ export const insertElementAtNewLineInCallout = (editor, type, currentPath) => {
124
125
  at: insertPath
125
126
  });
126
127
  Transforms.select(editor, insertPath);
128
+ };
129
+ export const getCalloutMenuPosition = (element, editor) => {
130
+ const {
131
+ top,
132
+ left
133
+ } = element.getBoundingClientRect();
134
+ const menuTop = top - 42; // top = top distance - menu height
135
+ const newMenuPosition = {
136
+ top: menuTop,
137
+ left: left // left = callout left distance
138
+ };
139
+ // 165 is distance with browser top
140
+ if (editor.editorType === DOCUMENT_PLUGIN_EDITOR && menuTop < 165) {
141
+ newMenuPosition['display'] = 'none';
142
+ }
143
+ return newMenuPosition;
127
144
  };
@@ -17,8 +17,7 @@ const withCallout = editor => {
17
17
  insertFragment,
18
18
  deleteBackward,
19
19
  onHotKeyDown,
20
- insertData,
21
- onCopy
20
+ insertData
22
21
  } = editor;
23
22
  const newEditor = editor;
24
23
  newEditor.deleteBackward = unit => {
@@ -7,6 +7,7 @@ import { CALLOUT_COLOR_MAP, CALLOUT_ICON_MAP } from '../constant';
7
7
  import { INTERNAL_EVENT } from '../../../../constants';
8
8
  import EventBus from '../../../../utils/event-bus';
9
9
  import { useScrollContext } from '../../../../hooks/use-scroll-context';
10
+ import { getCalloutMenuPosition } from '../helper';
10
11
  import CalloutHoverMenu from './callout-hover-menu';
11
12
  import './index.css';
12
13
  const renderCallout = (_ref, editor) => {
@@ -63,22 +64,10 @@ const renderCallout = (_ref, editor) => {
63
64
  if (readOnly) return;
64
65
  if (!isShowColorSelector) return;
65
66
  if (e.currentTarget.scrollTop) {
66
- const {
67
- top,
68
- left
69
- } = calloutRef.current.getBoundingClientRect();
70
- const menuTop = top - 36; // top = top distance - menu height
71
- const newMenuPosition = {
72
- top: menuTop,
73
- left: left // left = code-block left distance
74
- };
75
- // 165 is distance with browser top
76
- if (menuTop < 165) {
77
- newMenuPosition['display'] = 'none';
78
- }
79
- setPopoverPosition(newMenuPosition);
67
+ const menuPosition = getCalloutMenuPosition(calloutRef.current, editor);
68
+ setPopoverPosition(menuPosition);
80
69
  }
81
- }, [isShowColorSelector, readOnly]);
70
+ }, [editor, isShowColorSelector, readOnly]);
82
71
  useEffect(() => {
83
72
  const eventBus = EventBus.getInstance();
84
73
  const unsubscribe = eventBus.subscribe(INTERNAL_EVENT.CLOSE_CALLOUT_COLOR_PICKER, handleCloseColorSelector);
@@ -102,22 +91,10 @@ const renderCallout = (_ref, editor) => {
102
91
  }, [isSelected]);
103
92
  const handleDisplayColorSelector = useCallback(() => {
104
93
  if (readOnly) return;
105
- const {
106
- top,
107
- left
108
- } = calloutRef.current.getBoundingClientRect();
109
- const menuTop = top - 42; // top = top distance - menu height
110
- const newMenuPosition = {
111
- top: menuTop,
112
- left: left // left = callout left distance
113
- };
114
- // 165 is distance with browser top
115
- if (menuTop < 165) {
116
- newMenuPosition['display'] = 'none';
117
- }
118
- setPopoverPosition(newMenuPosition);
94
+ const menuPosition = getCalloutMenuPosition(calloutRef.current, editor);
95
+ setPopoverPosition(menuPosition);
119
96
  setIsShowColorSelector(true);
120
- }, [readOnly]);
97
+ }, [editor, readOnly]);
121
98
  const handleClick = useCallback(e => {
122
99
  handleDisplayColorSelector();
123
100
  }, [handleDisplayColorSelector]);
@@ -1,6 +1,6 @@
1
- import { Transforms, Editor, Element } from '@seafile/slate';
2
- import { CHECK_LIST_ITEM, PARAGRAPH, ELEMENT_TYPE, INSERT_POSITION } from '../../constants';
3
- import { getSelectedNodeByType, generateEmptyElement } from '../../core';
1
+ import { Transforms, Editor, Element, Node } from '@seafile/slate';
2
+ import { CHECK_LIST_ITEM, PARAGRAPH, ELEMENT_TYPE, INSERT_POSITION, ORDERED_LIST, UNORDERED_LIST } from '../../constants';
3
+ import { getSelectedNodeByType, generateEmptyElement, isMultiLevelList } from '../../core';
4
4
  export const isMenuDisabled = (editor, readonly) => {
5
5
  if (readonly) return true;
6
6
  if (editor.selection == null) return true;
@@ -19,7 +19,7 @@ export const isMenuDisabled = (editor, readonly) => {
19
19
  } = element;
20
20
  if (type === ELEMENT_TYPE.CODE_LINE) return true;
21
21
  if (type === ELEMENT_TYPE.CODE_BLOCK) return true;
22
- if (type === ELEMENT_TYPE.LIST_ITEM) return true;
22
+ if ([ORDERED_LIST, UNORDERED_LIST].includes(type) && isMultiLevelList(element)) return true;
23
23
  if (type === ELEMENT_TYPE.TABLE) return true;
24
24
  if (type === ELEMENT_TYPE.TABLE_ROW) return true;
25
25
  if (type === ELEMENT_TYPE.TABLE_CELL) return true;
@@ -33,6 +33,27 @@ export const getCheckListItemType = editor => {
33
33
  if (!node) return PARAGRAPH;
34
34
  return node.type;
35
35
  };
36
+ export const convertToCheck = (editor, listNode, listPath) => {
37
+ const checkList = [];
38
+ const {
39
+ children
40
+ } = listNode || {};
41
+ children.forEach(item => {
42
+ const text = Node.string(item);
43
+ const checkNode = generateEmptyElement(CHECK_LIST_ITEM, {}, text);
44
+ checkList.push(checkNode);
45
+ });
46
+ Transforms.removeNodes(editor, {
47
+ at: [listPath[0]]
48
+ });
49
+ Transforms.insertNodes(editor, checkList, {
50
+ at: [listPath[0]]
51
+ });
52
+ Transforms.select(editor, {
53
+ path: [listPath[0], 0],
54
+ offset: 0
55
+ });
56
+ };
36
57
  export const setCheckListItemType = (editor, newType, insertPosition) => {
37
58
  if (insertPosition === INSERT_POSITION.AFTER) {
38
59
  const p = generateEmptyElement(PARAGRAPH);
@@ -42,6 +63,14 @@ export const setCheckListItemType = (editor, newType, insertPosition) => {
42
63
  });
43
64
  Transforms.select(editor, [path[0] + 1]);
44
65
  }
66
+ const path = Editor.path(editor, editor.selection);
67
+ if (path) {
68
+ const [targetNode, targetPath] = Editor.node(editor, [path[0]]);
69
+ if (targetNode && [ORDERED_LIST, UNORDERED_LIST].includes(targetNode === null || targetNode === void 0 ? void 0 : targetNode.type)) {
70
+ convertToCheck(editor, targetNode, targetPath);
71
+ return;
72
+ }
73
+ }
45
74
  Transforms.setNodes(editor, {
46
75
  type: newType
47
76
  });
@@ -1,4 +1,4 @@
1
- import React, { useCallback, useEffect, useMemo, useState } from 'react';
1
+ import React, { useCallback, useEffect, useState } from 'react';
2
2
  import { Input } from 'reactstrap';
3
3
  import { useTranslation, withTranslation } from 'react-i18next';
4
4
  import Tooltip from '../../../../../components/tooltip';
@@ -183,4 +183,20 @@ export const isWeChat = () => {
183
183
  let isWeChat = ua.match(/MicroMessenger/i) === 'micromessenger';
184
184
  let isEnterpriseWeChat = ua.match(/MicroMessenger/i) === 'micromessenger' && ua.match(/wxwork/i) === 'wxwork';
185
185
  return isEnterpriseWeChat || isWeChat;
186
+ };
187
+ export const getMenuPosition = element => {
188
+ if (!element) return {};
189
+ const {
190
+ top,
191
+ left,
192
+ width
193
+ } = element.getBoundingClientRect();
194
+ // top = top distance - menu height
195
+ const menuTop = top - 42;
196
+ // left = left distance - (menu width / 2) + (link with / 2)
197
+ const menuLeft = left - 140 / 2 + width / 2;
198
+ return {
199
+ top: menuTop,
200
+ left: menuLeft
201
+ };
186
202
  };
@@ -7,7 +7,7 @@
7
7
  border: 1px solid #e5e5e5;
8
8
  border-radius: 3px;
9
9
  box-shadow: 0 1px 0 rgba(0, 0, 0, 0.08);
10
- z-index: 1000;
10
+ z-index: 101;
11
11
  }
12
12
 
13
13
  .link-op-menu .link-op-menu-triangle {
@@ -3,7 +3,7 @@ import { createPortal } from 'react-dom';
3
3
  import { useTranslation } from 'react-i18next';
4
4
  import { useReadOnly } from '@seafile/slate-react';
5
5
  import { isWeChat } from '../helpers';
6
- import '../../../../assets/css/textlink-hovermenu.css';
6
+ import './index.css';
7
7
  const LinkHover = _ref => {
8
8
  let {
9
9
  editor,
@@ -1,20 +1,33 @@
1
1
  import _defineProperty from "@babel/runtime/helpers/esm/defineProperty";
2
2
  import React from 'react';
3
3
  import { Range } from '@seafile/slate';
4
- import { unWrapLinkNode } from './helpers';
4
+ import { getMenuPosition, unWrapLinkNode } from './helpers';
5
5
  import LinkHover from './hover';
6
6
  import EventBus from '../../../utils/event-bus';
7
- import { INTERNAL_EVENT } from '../../../constants';
7
+ import { DOCUMENT_PLUGIN_EDITOR, INTERNAL_EVENT } from '../../../constants';
8
8
  import { ELEMENT_TYPE } from '../../constants';
9
9
  import InlineBugFixer from '../../commons/Inline-bug-fix-wrapper';
10
- class LinkHoverMenuComponent extends React.Component {
10
+ import { ScrollContext } from '../../../hooks/use-scroll-context';
11
+ class Link extends React.Component {
11
12
  constructor(props) {
12
13
  super(props);
13
14
  _defineProperty(this, "registerEventHandle", () => {
14
15
  document.addEventListener('click', this.onHideLinkMenu);
16
+ const {
17
+ scrollRef
18
+ } = this.context;
19
+ if (scrollRef.current) {
20
+ scrollRef.current.addEventListener('scroll', this.onScroll);
21
+ }
15
22
  });
16
23
  _defineProperty(this, "unregisterEventHandle", () => {
17
24
  document.removeEventListener('click', this.onHideLinkMenu);
25
+ const {
26
+ scrollRef
27
+ } = this.context;
28
+ if (scrollRef.current) {
29
+ scrollRef.current.addEventListener('scroll', this.onScroll);
30
+ }
18
31
  });
19
32
  _defineProperty(this, "onHideLinkMenu", () => {
20
33
  this.setState({
@@ -23,22 +36,25 @@ class LinkHoverMenuComponent extends React.Component {
23
36
  this.unregisterEventHandle();
24
37
  });
25
38
  });
26
- _defineProperty(this, "onLinkClick", e => {
39
+ _defineProperty(this, "onScroll", e => {
40
+ this.setPosition(this.linkRef);
41
+ });
42
+ _defineProperty(this, "setPosition", element => {
27
43
  const {
28
- top,
29
- left,
30
- width
31
- } = e.target.getBoundingClientRect();
32
- // top = top distance - menu height
33
- const menuTop = top - 42;
34
- // left = left distance - (menu width / 2) + (link with / 2)
35
- const menuLeft = left - 140 / 2 + width / 2;
44
+ editor
45
+ } = this.props;
46
+ const menuPosition = getMenuPosition(element);
47
+ if (editor.editorType === DOCUMENT_PLUGIN_EDITOR && menuPosition.top < 165) {
48
+ menuPosition['display'] = 'none';
49
+ }
36
50
  this.setState({
37
- isShowLinkMenu: true,
38
- menuPosition: {
39
- top: menuTop,
40
- left: menuLeft
41
- }
51
+ menuPosition
52
+ });
53
+ });
54
+ _defineProperty(this, "onLinkClick", e => {
55
+ this.setPosition(e.target);
56
+ this.setState({
57
+ isShowLinkMenu: true
42
58
  });
43
59
  setTimeout(() => {
44
60
  this.registerEventHandle();
@@ -59,6 +75,9 @@ class LinkHoverMenuComponent extends React.Component {
59
75
  element
60
76
  });
61
77
  });
78
+ _defineProperty(this, "setRef", ref => {
79
+ this.linkRef = ref;
80
+ });
62
81
  this.state = {
63
82
  isShowLinkMenu: false,
64
83
  menuPosition: null
@@ -94,6 +113,7 @@ class LinkHoverMenuComponent extends React.Component {
94
113
  }, attributes, {
95
114
  onClick: this.onLinkClick
96
115
  }), /*#__PURE__*/React.createElement("span", {
116
+ ref: this.setRef,
97
117
  className: "virtual-link",
98
118
  title: element.title
99
119
  }, /*#__PURE__*/React.createElement(InlineBugFixer, null), children, /*#__PURE__*/React.createElement(InlineBugFixer, null))), isShowLinkMenu && (this.props.readonly || Range.isCollapsed(editor.selection)) && /*#__PURE__*/React.createElement(LinkHover, {
@@ -105,8 +125,9 @@ class LinkHoverMenuComponent extends React.Component {
105
125
  }));
106
126
  }
107
127
  }
128
+ _defineProperty(Link, "contextType", ScrollContext);
108
129
  const renderLink = (props, editor, readonly) => {
109
- return /*#__PURE__*/React.createElement(LinkHoverMenuComponent, Object.assign({}, props, {
130
+ return /*#__PURE__*/React.createElement(Link, Object.assign({}, props, {
110
131
  editor: editor,
111
132
  readonly: readonly
112
133
  }));
@@ -1,5 +1,5 @@
1
1
  import { Editor, Path, Range, Transforms } from '@seafile/slate';
2
- import { INSERT_POSITION, ORDERED_LIST, PARAGRAPH } from '../../../constants';
2
+ import { ORDERED_LIST, PARAGRAPH } from '../../../constants';
3
3
  import { getBeforeText, setListType } from '../helpers';
4
4
  import { focusEditor, getLastChild, getPreviousPath } from '../../../core';
5
5
  import { generateEmptyListItem } from '../model';
@@ -136,7 +136,7 @@ const ParticipantPopover = _ref => {
136
136
  setActiveCollaboratorIndex(nextActiveCollaboratorIndex);
137
137
  }, [searchedCollaborators, activeCollaboratorIndex]);
138
138
  const onSelectCollaborator = useCallback(collaborator => {
139
- const [node, path] = getMentionTempIptEntry(editor);
139
+ const [, path] = getMentionTempIptEntry(editor);
140
140
  insertMention(editor, collaborator);
141
141
  addParticipants(collaborator.username);
142
142
  Transforms.removeNodes(editor, {
@@ -15,7 +15,6 @@
15
15
  .sdoc-table-alignment-menu .sdoc-dropdown-menu-item .sdoc-check-mark {
16
16
  display: none;
17
17
  font-size: 16px !important;
18
- color: #6f59ff;
19
18
  }
20
19
  .sdoc-table-alignment-menu .sdoc-dropdown-menu-item .sdoc-check-mark.active {
21
20
  display: inline;
@@ -3,12 +3,13 @@ import slugid from 'slugid';
3
3
  import { ReactEditor } from '@seafile/slate-react';
4
4
  import copy from 'copy-to-clipboard';
5
5
  import { toggleList } from '../../plugins/list/transforms';
6
- import { generateEmptyElement } from '../../core';
6
+ import { generateEmptyElement, findPath, isMultiLevelList } from '../../core';
7
7
  import { generateEmptyList } from '../../plugins/list/model';
8
8
  import { setClipboardCodeBlockData } from '../../plugins/code-block/helpers';
9
9
  import { ORDERED_LIST, UNORDERED_LIST, PARAGRAPH, CHECK_LIST_ITEM, IMAGE, TABLE, CODE_BLOCK, BLOCKQUOTE, LIST_ITEM_CORRELATION_TYPE, ADD_POSITION_OFFSET_TYPE, INSERT_POSITION, ELEMENT_TYPE, CALL_OUT } from '../../constants';
10
10
  import { EMPTY_SELECTED_RANGE } from '../../plugins/table/constants';
11
11
  import { unwrapCallout, wrapCallout } from '../../plugins/callout/helper';
12
+ import { convertToCheck } from '../../plugins/check-list/helpers';
12
13
  import { getHeaderHeight } from '../../../utils/dom-utils';
13
14
  export const onSetNodeType = (editor, element, type) => {
14
15
  if (!type) return;
@@ -21,6 +22,12 @@ export const onSetNodeType = (editor, element, type) => {
21
22
  return;
22
23
  }
23
24
  if (type === CHECK_LIST_ITEM) {
25
+ const path = findPath(editor, element);
26
+ const [targetNode, targetPath] = Editor.node(editor, [path[0]]) || [];
27
+ if (targetNode && [ORDERED_LIST, UNORDERED_LIST].includes(targetNode === null || targetNode === void 0 ? void 0 : targetNode.type) && !isMultiLevelList(targetNode)) {
28
+ convertToCheck(editor, targetNode, targetPath);
29
+ return;
30
+ }
24
31
  const newType = element.type === CHECK_LIST_ITEM ? PARAGRAPH : CHECK_LIST_ITEM;
25
32
  Transforms.setNodes(editor, {
26
33
  type: newType
@@ -3,8 +3,9 @@ import { UncontrolledPopover } from 'reactstrap';
3
3
  import { withTranslation } from 'react-i18next';
4
4
  import { ReactEditor, useSlateStatic } from '@seafile/slate-react';
5
5
  import { onSetNodeType } from './helpers';
6
- import { SIDE_TRANSFORM_MENUS_CONFIG, LIST_ITEM_SUPPORTED_TRANSFORMATION, LIST_ITEM_CORRELATION_TYPE, BLOCKQUOTE, CALL_OUT, HEADERS } from '../../constants';
6
+ import { SIDE_TRANSFORM_MENUS_CONFIG, LIST_ITEM_SUPPORTED_TRANSFORMATION, LIST_ITEM_CORRELATION_TYPE, BLOCKQUOTE, CALL_OUT, HEADERS, ORDERED_LIST, UNORDERED_LIST, CHECK_LIST_ITEM } from '../../constants';
7
7
  import DropdownMenuItem from '../../commons/dropdown-menu-item';
8
+ import { isMultiLevelList } from '../../core';
8
9
  const TransformMenus = _ref => {
9
10
  let {
10
11
  target,
@@ -37,6 +38,11 @@ const TransformMenus = _ref => {
37
38
  if (HEADERS.includes(highestNode.type)) {
38
39
  newSideMenusConfig = SIDE_TRANSFORM_MENUS_CONFIG.filter(item => item.type !== BLOCKQUOTE);
39
40
  }
41
+
42
+ // Multi-level list items cannot be converted to checks
43
+ if ([ORDERED_LIST, UNORDERED_LIST].includes(highestNode.type) && isMultiLevelList(highestNode)) {
44
+ newSideMenusConfig = SIDE_TRANSFORM_MENUS_CONFIG.filter(item => item.type !== CHECK_LIST_ITEM);
45
+ }
40
46
  }
41
47
  return newSideMenusConfig;
42
48
  // 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.27",
3
+ "version": "1.0.29",
4
4
  "private": false,
5
5
  "description": "This is a sdoc editor",
6
6
  "main": "dist/index.js",
@@ -16,7 +16,7 @@
16
16
  "Quote": "Quote",
17
17
  "Ordered_list": "Ordered list",
18
18
  "Unordered_list": "Unordered list",
19
- "Check_list_item": "Check list item",
19
+ "Check_list": "Check list",
20
20
  "Insert_image": "Insert image",
21
21
  "Insert_formula": "Insert formula",
22
22
  "Formula": "Formula",
@@ -16,7 +16,7 @@
16
16
  "Quote": "Цитата",
17
17
  "Ordered_list": "Нумерованный список",
18
18
  "Unordered_list": "Маркированный список",
19
- "Check_list": "Check list",
19
+ "Check_list": "Контрольный список",
20
20
  "Insert_image": "Вставить изображение",
21
21
  "Insert_formula": "Вставить формулу",
22
22
  "Formula": "Формула",