@seafile/sdoc-editor 2.0.2 → 2.0.4
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.
- package/dist/basic-sdk/extension/commons/search-list/index.css +28 -0
- package/dist/basic-sdk/extension/commons/search-list/index.js +148 -0
- package/dist/basic-sdk/extension/plugins/seatable-column/menu/column-list-item.js +36 -0
- package/dist/basic-sdk/extension/plugins/seatable-column/menu/column-list-menu.css +4 -2
- package/dist/basic-sdk/extension/plugins/seatable-column/menu/column-list-menu.js +8 -13
- package/dist/basic-sdk/extension/plugins/seatable-column/render-elem.js +36 -7
- package/dist/components/toast/toaster.js +3 -2
- package/package.json +2 -2
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
.sdoc-search-list {
|
|
2
|
+
display: flex;
|
|
3
|
+
height: 100%;
|
|
4
|
+
width: 100%;
|
|
5
|
+
flex-direction: column;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
.sdoc-search-list .sdoc-search-list-wrapper {
|
|
9
|
+
padding: 12px;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
.sdoc-search-list .sdoc-search-list-wrapper>input {
|
|
13
|
+
font-size: 12px;
|
|
14
|
+
max-height: 30px;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
.sdoc-search-list .sdoc-search-list-content-wrapper {
|
|
18
|
+
min-height: 0;
|
|
19
|
+
min-width: 0;
|
|
20
|
+
flex: 1;
|
|
21
|
+
overflow: auto;
|
|
22
|
+
max-height: 300px;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
.sdoc-search-list .sdoc-search-list-with-no-results {
|
|
26
|
+
font-size: 12px;
|
|
27
|
+
padding: 4px 16px;
|
|
28
|
+
}
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault").default;
|
|
4
|
+
var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard").default;
|
|
5
|
+
Object.defineProperty(exports, "__esModule", {
|
|
6
|
+
value: true
|
|
7
|
+
});
|
|
8
|
+
exports.default = SearchList;
|
|
9
|
+
var _react = _interopRequireWildcard(require("react"));
|
|
10
|
+
var _reactI18next = require("react-i18next");
|
|
11
|
+
var _reactstrap = require("reactstrap");
|
|
12
|
+
var _keyCodes = _interopRequireDefault(require("../../../../constants/key-codes"));
|
|
13
|
+
require("./index.css");
|
|
14
|
+
function SearchList(_ref) {
|
|
15
|
+
let {
|
|
16
|
+
list: originalList,
|
|
17
|
+
listItem: ListItem,
|
|
18
|
+
onListItemClick,
|
|
19
|
+
onEscClick
|
|
20
|
+
} = _ref;
|
|
21
|
+
const {
|
|
22
|
+
t
|
|
23
|
+
} = (0, _reactI18next.useTranslation)('sdoc-editor');
|
|
24
|
+
const inputWrapperRef = (0, _react.useRef)(null);
|
|
25
|
+
const isComposingRef = (0, _react.useRef)(null);
|
|
26
|
+
const listRefs = (0, _react.useRef)([]);
|
|
27
|
+
const [searchedList, setSearchedList] = (0, _react.useState)(originalList);
|
|
28
|
+
const [currentSelectIndex, setCurrentSelectIndex] = (0, _react.useState)(-1);
|
|
29
|
+
|
|
30
|
+
// search input
|
|
31
|
+
const onChange = (0, _react.useCallback)(event => {
|
|
32
|
+
if (isComposingRef.current) return;
|
|
33
|
+
const value = event.target.value.trim();
|
|
34
|
+
if (value) {
|
|
35
|
+
const list = originalList.filter(item => item.label.indexOf(value) > -1);
|
|
36
|
+
setSearchedList(list);
|
|
37
|
+
} else {
|
|
38
|
+
setSearchedList(originalList);
|
|
39
|
+
}
|
|
40
|
+
}, [originalList]);
|
|
41
|
+
const onCompositionStart = (0, _react.useCallback)(() => {
|
|
42
|
+
isComposingRef.current = true;
|
|
43
|
+
}, []);
|
|
44
|
+
const onCompositionEnd = (0, _react.useCallback)(e => {
|
|
45
|
+
isComposingRef.current = false;
|
|
46
|
+
onChange(e);
|
|
47
|
+
}, [onChange]);
|
|
48
|
+
|
|
49
|
+
// search content list
|
|
50
|
+
const onItemClick = (0, _react.useCallback)(item => {
|
|
51
|
+
onListItemClick && onListItemClick(item);
|
|
52
|
+
}, [onListItemClick]);
|
|
53
|
+
const onHandleInputFocus = (0, _react.useCallback)(isFocus => {
|
|
54
|
+
if (inputWrapperRef.current) {
|
|
55
|
+
queueMicrotask(() => {
|
|
56
|
+
isFocus ? inputWrapperRef.current.focus() : inputWrapperRef.current.blur();
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
}, []);
|
|
60
|
+
(0, _react.useEffect)(() => {
|
|
61
|
+
if (currentSelectIndex === -1) {
|
|
62
|
+
onHandleInputFocus(true);
|
|
63
|
+
} else {
|
|
64
|
+
onHandleInputFocus(false);
|
|
65
|
+
}
|
|
66
|
+
}, [currentSelectIndex, onHandleInputFocus]);
|
|
67
|
+
const handleClick = (0, _react.useCallback)(event => {
|
|
68
|
+
if (inputWrapperRef !== null && inputWrapperRef !== void 0 && inputWrapperRef.current.contains(event.target) || inputWrapperRef.current === event.target) {
|
|
69
|
+
event.stopPropagation();
|
|
70
|
+
event.nativeEvent && event.nativeEvent.stopImmediatePropagation && event.nativeEvent.stopImmediatePropagation();
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
}, []);
|
|
74
|
+
const scrollIntoView = (0, _react.useCallback)(index => {
|
|
75
|
+
listRefs.current[index].scrollIntoView({
|
|
76
|
+
behavior: 'smooth',
|
|
77
|
+
block: 'center',
|
|
78
|
+
inline: 'nearest'
|
|
79
|
+
});
|
|
80
|
+
}, []);
|
|
81
|
+
const handleKeyDown = (0, _react.useCallback)(e => {
|
|
82
|
+
const {
|
|
83
|
+
UpArrow,
|
|
84
|
+
DownArrow,
|
|
85
|
+
Enter,
|
|
86
|
+
Esc
|
|
87
|
+
} = _keyCodes.default;
|
|
88
|
+
const {
|
|
89
|
+
keyCode
|
|
90
|
+
} = e;
|
|
91
|
+
if (keyCode === UpArrow) {
|
|
92
|
+
e.preventDefault();
|
|
93
|
+
if (currentSelectIndex > -1) {
|
|
94
|
+
setCurrentSelectIndex(currentSelectIndex - 1);
|
|
95
|
+
scrollIntoView(currentSelectIndex - 1);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
if (keyCode === DownArrow) {
|
|
99
|
+
e.preventDefault();
|
|
100
|
+
if (currentSelectIndex === searchedList.length - 1) return;
|
|
101
|
+
if (currentSelectIndex < searchedList.length - 1) {
|
|
102
|
+
setCurrentSelectIndex(currentSelectIndex + 1);
|
|
103
|
+
scrollIntoView(currentSelectIndex + 1);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
if (keyCode === Enter) {
|
|
107
|
+
e.preventDefault();
|
|
108
|
+
const item = searchedList[currentSelectIndex];
|
|
109
|
+
onItemClick(item);
|
|
110
|
+
}
|
|
111
|
+
if (keyCode === Esc) {
|
|
112
|
+
e.preventDefault();
|
|
113
|
+
onEscClick && onEscClick();
|
|
114
|
+
}
|
|
115
|
+
}, [currentSelectIndex, onEscClick, onItemClick, scrollIntoView, searchedList]);
|
|
116
|
+
(0, _react.useEffect)(() => {
|
|
117
|
+
document.addEventListener('mousedown', handleClick);
|
|
118
|
+
document.addEventListener('keydown', handleKeyDown);
|
|
119
|
+
return () => {
|
|
120
|
+
document.removeEventListener('keydown', handleKeyDown);
|
|
121
|
+
document.removeEventListener('click', handleClick);
|
|
122
|
+
};
|
|
123
|
+
}, [handleClick, handleKeyDown]);
|
|
124
|
+
return /*#__PURE__*/_react.default.createElement("div", {
|
|
125
|
+
className: "sdoc-search-list"
|
|
126
|
+
}, /*#__PURE__*/_react.default.createElement("div", {
|
|
127
|
+
className: "sdoc-search-list-wrapper"
|
|
128
|
+
}, /*#__PURE__*/_react.default.createElement(_reactstrap.Input, {
|
|
129
|
+
innerRef: inputWrapperRef,
|
|
130
|
+
placeholder: t('Search_action'),
|
|
131
|
+
onChange: onChange,
|
|
132
|
+
onCompositionStart: onCompositionStart,
|
|
133
|
+
onCompositionEnd: onCompositionEnd
|
|
134
|
+
})), /*#__PURE__*/_react.default.createElement("div", {
|
|
135
|
+
className: "sdoc-search-list-content-wrapper"
|
|
136
|
+
}, searchedList.length === 0 && /*#__PURE__*/_react.default.createElement("div", {
|
|
137
|
+
className: "sdoc-search-list-with-no-results"
|
|
138
|
+
}, t('No_results')), searchedList.map((item, index) => {
|
|
139
|
+
const isSelected = index === currentSelectIndex;
|
|
140
|
+
return /*#__PURE__*/_react.default.createElement(ListItem, {
|
|
141
|
+
innerRef: el => listRefs.current[index] = el,
|
|
142
|
+
key: index,
|
|
143
|
+
item: item,
|
|
144
|
+
onItemClick: onItemClick,
|
|
145
|
+
isSelected: isSelected
|
|
146
|
+
});
|
|
147
|
+
})));
|
|
148
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard").default;
|
|
4
|
+
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault").default;
|
|
5
|
+
Object.defineProperty(exports, "__esModule", {
|
|
6
|
+
value: true
|
|
7
|
+
});
|
|
8
|
+
exports.default = ColumnListItem;
|
|
9
|
+
var _classnames = _interopRequireDefault(require("classnames"));
|
|
10
|
+
var _react = _interopRequireWildcard(require("react"));
|
|
11
|
+
function ColumnListItem(_ref) {
|
|
12
|
+
let {
|
|
13
|
+
innerRef,
|
|
14
|
+
item,
|
|
15
|
+
onItemClick,
|
|
16
|
+
isSelected
|
|
17
|
+
} = _ref;
|
|
18
|
+
const onMouseDown = (0, _react.useCallback)(() => {
|
|
19
|
+
onItemClick(item);
|
|
20
|
+
}, [onItemClick, item]);
|
|
21
|
+
const clazzNames = (0, _classnames.default)('column-list-menu-item-container', {
|
|
22
|
+
'selected': isSelected
|
|
23
|
+
});
|
|
24
|
+
return /*#__PURE__*/_react.default.createElement("div", {
|
|
25
|
+
ref: innerRef,
|
|
26
|
+
key: item.value,
|
|
27
|
+
className: clazzNames,
|
|
28
|
+
onClick: onMouseDown
|
|
29
|
+
}, /*#__PURE__*/_react.default.createElement("div", {
|
|
30
|
+
className: "column-list-menu-item"
|
|
31
|
+
}, /*#__PURE__*/_react.default.createElement("span", {
|
|
32
|
+
className: `control-icon ${item.iconClass}`
|
|
33
|
+
}), /*#__PURE__*/_react.default.createElement("span", {
|
|
34
|
+
className: "control-label"
|
|
35
|
+
}, item.label)));
|
|
36
|
+
}
|
|
@@ -8,8 +8,6 @@
|
|
|
8
8
|
background-color: #fff;
|
|
9
9
|
min-width: 12rem;
|
|
10
10
|
width: 200px;
|
|
11
|
-
max-height: 300px;
|
|
12
|
-
overflow: auto;
|
|
13
11
|
padding: 8px 0;
|
|
14
12
|
}
|
|
15
13
|
|
|
@@ -46,3 +44,7 @@
|
|
|
46
44
|
background-color: #f5f5f5;
|
|
47
45
|
cursor: pointer;
|
|
48
46
|
}
|
|
47
|
+
|
|
48
|
+
.column-list-menu .column-list-menu-item-container.selected {
|
|
49
|
+
background-color: #e3e3e3;
|
|
50
|
+
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
|
+
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault").default;
|
|
3
4
|
var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard").default;
|
|
4
5
|
Object.defineProperty(exports, "__esModule", {
|
|
5
6
|
value: true
|
|
@@ -10,6 +11,8 @@ var _column = require("../constants/column");
|
|
|
10
11
|
var _helpers = require("../helpers");
|
|
11
12
|
var _elementType = require("../../../constants/element-type");
|
|
12
13
|
var _utils = require("../../../utils");
|
|
14
|
+
var _searchList = _interopRequireDefault(require("../../../commons/search-list"));
|
|
15
|
+
var _columnListItem = _interopRequireDefault(require("./column-list-item"));
|
|
13
16
|
require("./column-list-menu.css");
|
|
14
17
|
const NOT_SUPPORT_COLUMN_TYPES = ['button', 'file'];
|
|
15
18
|
function ColumnListMenu(_ref) {
|
|
@@ -51,7 +54,7 @@ function ColumnListMenu(_ref) {
|
|
|
51
54
|
const isActive = editor => {
|
|
52
55
|
return (0, _helpers.getColumnType)(editor) === _elementType.SEATABLE_COLUMN;
|
|
53
56
|
};
|
|
54
|
-
const
|
|
57
|
+
const onListItemClick = (0, _react.useCallback)(option => {
|
|
55
58
|
const active = isActive(editor);
|
|
56
59
|
(0, _helpers.insertSeaTableColumn)(editor, active, option, insertPosition);
|
|
57
60
|
toggle && toggle();
|
|
@@ -60,17 +63,9 @@ function ColumnListMenu(_ref) {
|
|
|
60
63
|
ref: columnRef,
|
|
61
64
|
className: "column-list-menu",
|
|
62
65
|
style: computedStyle
|
|
63
|
-
},
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
onClick: () => onMousedown(option)
|
|
68
|
-
}, /*#__PURE__*/_react.default.createElement("div", {
|
|
69
|
-
className: "column-list-menu-item"
|
|
70
|
-
}, /*#__PURE__*/_react.default.createElement("span", {
|
|
71
|
-
className: `control-icon ${option.iconClass}`
|
|
72
|
-
}), /*#__PURE__*/_react.default.createElement("span", {
|
|
73
|
-
className: "control-label"
|
|
74
|
-
}, option.label)));
|
|
66
|
+
}, /*#__PURE__*/_react.default.createElement(_searchList.default, {
|
|
67
|
+
list: options,
|
|
68
|
+
listItem: _columnListItem.default,
|
|
69
|
+
onListItemClick: onListItemClick
|
|
75
70
|
}));
|
|
76
71
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
|
+
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault").default;
|
|
3
4
|
var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard").default;
|
|
4
5
|
Object.defineProperty(exports, "__esModule", {
|
|
5
6
|
value: true
|
|
@@ -7,6 +8,7 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
7
8
|
exports.default = void 0;
|
|
8
9
|
var _react = _interopRequireWildcard(require("react"));
|
|
9
10
|
var _slateReact = require("@seafile/slate-react");
|
|
11
|
+
var _mdToHtml = _interopRequireDefault(require("../../../../slate-convert/md-to-html"));
|
|
10
12
|
const Column = _ref => {
|
|
11
13
|
let {
|
|
12
14
|
props,
|
|
@@ -19,15 +21,34 @@ const Column = _ref => {
|
|
|
19
21
|
} = props;
|
|
20
22
|
const isReadOnly = (0, _slateReact.useReadOnly)();
|
|
21
23
|
const isSelected = (0, _slateReact.useSelected)();
|
|
24
|
+
const [columnValue, setColumnValue] = (0, _react.useState)('');
|
|
22
25
|
const data = element.data || {};
|
|
23
26
|
const {
|
|
24
|
-
key: columnKey
|
|
25
|
-
name: columnName
|
|
27
|
+
key: columnKey
|
|
26
28
|
} = data;
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
}
|
|
29
|
+
const column = editor.columns.find(item => item.key === columnKey);
|
|
30
|
+
const isLongTextColumn = (0, _react.useMemo)(() => {
|
|
31
|
+
return column && column.type === 'long-text';
|
|
32
|
+
}, [column]);
|
|
33
|
+
(0, _react.useEffect)(() => {
|
|
34
|
+
const data = element.data || {};
|
|
35
|
+
const {
|
|
36
|
+
key: columnKey,
|
|
37
|
+
name: columnName
|
|
38
|
+
} = data;
|
|
39
|
+
let displayValue = columnName ? `{${columnName}}` : '';
|
|
40
|
+
if (editor.getColumnCellValue) {
|
|
41
|
+
displayValue = editor.getColumnCellValue(columnKey) || 'null';
|
|
42
|
+
if (!isLongTextColumn) {
|
|
43
|
+
setColumnValue(displayValue);
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
_mdToHtml.default.process(displayValue).then(res => {
|
|
47
|
+
displayValue = String(res);
|
|
48
|
+
setColumnValue(displayValue);
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
}, [editor, element.data, isLongTextColumn]);
|
|
31
52
|
const [isClicked, setIsClicked] = (0, _react.useState)(false);
|
|
32
53
|
(0, _react.useEffect)(() => {
|
|
33
54
|
if (isSelected && !isReadOnly) {
|
|
@@ -50,6 +71,7 @@ const Column = _ref => {
|
|
|
50
71
|
margin: '0 10px',
|
|
51
72
|
border: '1px solid transparent',
|
|
52
73
|
userSelect: 'none',
|
|
74
|
+
display: 'inline-block',
|
|
53
75
|
...(isClicked && {
|
|
54
76
|
border: '1px solid red'
|
|
55
77
|
}),
|
|
@@ -80,7 +102,14 @@ const Column = _ref => {
|
|
|
80
102
|
};
|
|
81
103
|
return /*#__PURE__*/_react.default.createElement("span", Object.assign({}, attributes, {
|
|
82
104
|
style: style
|
|
83
|
-
}),
|
|
105
|
+
}), !isLongTextColumn && columnValue, isLongTextColumn && /*#__PURE__*/_react.default.createElement("div", {
|
|
106
|
+
style: {
|
|
107
|
+
padding: '10px'
|
|
108
|
+
},
|
|
109
|
+
dangerouslySetInnerHTML: {
|
|
110
|
+
__html: columnValue
|
|
111
|
+
}
|
|
112
|
+
}), children);
|
|
84
113
|
};
|
|
85
114
|
const renderColumn = (props, editor) => {
|
|
86
115
|
return /*#__PURE__*/_react.default.createElement(Column, {
|
|
@@ -7,7 +7,7 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
7
7
|
exports.default = void 0;
|
|
8
8
|
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/esm/defineProperty"));
|
|
9
9
|
var _react = _interopRequireDefault(require("react"));
|
|
10
|
-
var
|
|
10
|
+
var _client = require("react-dom/client");
|
|
11
11
|
var _toastManager = _interopRequireDefault(require("./toastManager"));
|
|
12
12
|
require("./index.css");
|
|
13
13
|
const isBrowser = typeof window !== 'undefined' && typeof window.document !== 'undefined';
|
|
@@ -66,7 +66,8 @@ class Toaster {
|
|
|
66
66
|
const container = document.createElement('div');
|
|
67
67
|
container.setAttribute('data-evergreen-toaster-container', '');
|
|
68
68
|
document.body.appendChild(container);
|
|
69
|
-
|
|
69
|
+
const root = (0, _client.createRoot)(container);
|
|
70
|
+
root.render( /*#__PURE__*/_react.default.createElement(_toastManager.default, {
|
|
70
71
|
bindNotify: this._bindNotify,
|
|
71
72
|
bindGetToasts: this._bindGetToasts,
|
|
72
73
|
bindCloseAll: this._bindCloseAll
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@seafile/sdoc-editor",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.4",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "This is a sdoc editor",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
"copy-to-clipboard": "^3.3.3",
|
|
17
17
|
"dayjs": "1.10.7",
|
|
18
18
|
"deep-copy": "1.4.2",
|
|
19
|
-
"dtable-ui-component": "
|
|
19
|
+
"dtable-ui-component": "6.0.0",
|
|
20
20
|
"is-hotkey": "0.2.0",
|
|
21
21
|
"is-url": "^1.2.4",
|
|
22
22
|
"lodash.isequal": "4.5.0",
|