@lobehub/editor 1.7.0 → 1.8.0
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/es/plugins/code/command/index.js +7 -7
- package/es/plugins/code/node/code.d.ts +2 -1
- package/es/plugins/code/node/code.js +23 -4
- package/es/plugins/code/plugin/index.js +13 -1
- package/es/plugins/code/plugin/registry.js +14 -7
- package/es/plugins/common/index.d.ts +1 -1
- package/es/plugins/common/index.js +1 -1
- package/es/plugins/common/node/cursor.js +8 -0
- package/es/plugins/common/plugin/index.js +0 -4
- package/es/plugins/markdown/service/shortcut.d.ts +5 -3
- package/es/plugins/markdown/service/shortcut.js +41 -33
- package/es/plugins/slash/plugin/index.js +28 -1
- package/es/plugins/slash/react/type.d.ts +19 -0
- package/es/plugins/slash/service/i-slash-service.d.ts +20 -2
- package/es/plugins/slash/service/i-slash-service.js +6 -3
- package/es/plugins/slash/utils/utils.js +8 -2
- package/es/plugins/table/react/TableActionMenu/style.js +1 -1
- package/es/plugins/table/react/TableHoverActions/index.js +4 -10
- package/es/plugins/table/react/TableHoverActions/style.js +2 -2
- package/es/react/ChatInput/ChatInput.js +124 -22
- package/es/react/ChatInput/style.d.ts +2 -0
- package/es/react/ChatInput/style.js +5 -3
- package/es/react/ChatInput/type.d.ts +14 -2
- package/es/react/ChatInputActions/components/useDisplayActionCount.d.ts +1 -1
- package/es/react/ChatInputActions/components/useDisplayActionCount.js +7 -7
- package/es/react/Editor/Editor.js +2 -2
- package/es/react/hooks/useSize.d.ts +13 -0
- package/es/react/{ChatInputActions/components/useContainerSize.js → hooks/useSize.js} +37 -3
- package/package.json +2 -1
- package/es/react/ChatInputActions/components/useContainerSize.d.ts +0 -9
|
@@ -4,7 +4,7 @@ function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len
|
|
|
4
4
|
import { $isCodeHighlightNode } from '@lexical/code';
|
|
5
5
|
import { $getSelection, $insertNodes, $isRangeSelection, COMMAND_PRIORITY_EDITOR, createCommand } from 'lexical';
|
|
6
6
|
import { $createCursorNode } from "../../common";
|
|
7
|
-
import { $createCodeNode, $isCodeInlineNode } from "../node/code";
|
|
7
|
+
import { $createCodeNode, $isCodeInlineNode, getCodeInlineNode } from "../node/code";
|
|
8
8
|
export var INSERT_CODEINLINE_COMMAND = createCommand('INSERT_CODEINLINE_COMMAND');
|
|
9
9
|
export function registerCodeInlineCommand(editor) {
|
|
10
10
|
return editor.registerCommand(INSERT_CODEINLINE_COMMAND, function () {
|
|
@@ -18,24 +18,24 @@ export function registerCodeInlineCommand(editor) {
|
|
|
18
18
|
if ($isCodeHighlightNode(focusNode) || $isCodeHighlightNode(anchorNode)) {
|
|
19
19
|
return false;
|
|
20
20
|
}
|
|
21
|
-
|
|
21
|
+
var code = getCodeInlineNode(focusNode);
|
|
22
|
+
if (code !== getCodeInlineNode(anchorNode)) {
|
|
22
23
|
return false;
|
|
23
24
|
}
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
var _iterator = _createForOfIteratorHelper(parentNode.getChildren().slice(0)),
|
|
25
|
+
if ($isCodeInlineNode(code)) {
|
|
26
|
+
var _iterator = _createForOfIteratorHelper(code.getChildren().slice(0)),
|
|
27
27
|
_step;
|
|
28
28
|
try {
|
|
29
29
|
for (_iterator.s(); !(_step = _iterator.n()).done;) {
|
|
30
30
|
var node = _step.value;
|
|
31
|
-
|
|
31
|
+
code.insertBefore(node);
|
|
32
32
|
}
|
|
33
33
|
} catch (err) {
|
|
34
34
|
_iterator.e(err);
|
|
35
35
|
} finally {
|
|
36
36
|
_iterator.f();
|
|
37
37
|
}
|
|
38
|
-
|
|
38
|
+
code.remove();
|
|
39
39
|
return true;
|
|
40
40
|
}
|
|
41
41
|
var codeNode = $createCodeNode(selection.getTextContent());
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { EditorConfig, LexicalEditor, SerializedElementNode } from 'lexical';
|
|
1
|
+
import { EditorConfig, LexicalEditor, LexicalNode, SerializedElementNode } from 'lexical';
|
|
2
2
|
import { CardLikeElementNode } from "../../common";
|
|
3
3
|
export type SerializedCodeNode = SerializedElementNode;
|
|
4
4
|
export declare class CodeNode extends CardLikeElementNode {
|
|
@@ -17,4 +17,5 @@ export declare class CodeNode extends CardLikeElementNode {
|
|
|
17
17
|
}
|
|
18
18
|
export declare function $createCodeNode(textContent?: string): CodeNode;
|
|
19
19
|
export declare function $isCodeInlineNode(node: unknown): node is CodeNode;
|
|
20
|
+
export declare function getCodeInlineNode(node: LexicalNode): LexicalNode | null;
|
|
20
21
|
export declare function $isSelectionInCodeInline(editor: LexicalEditor): boolean;
|
|
@@ -16,7 +16,7 @@ function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.g
|
|
|
16
16
|
/* eslint-disable @typescript-eslint/no-use-before-define */
|
|
17
17
|
import { addClassNamesToElement } from '@lexical/utils';
|
|
18
18
|
import { $applyNodeReplacement, $createTextNode, $getSelection, $isNodeSelection, $isRangeSelection } from 'lexical';
|
|
19
|
-
import { $createCursorNode, CardLikeElementNode } from "../../common";
|
|
19
|
+
import { $createCursorNode, $isCursorNode, CardLikeElementNode } from "../../common";
|
|
20
20
|
export var CodeNode = /*#__PURE__*/function (_CardLikeElementNode) {
|
|
21
21
|
_inherits(CodeNode, _CardLikeElementNode);
|
|
22
22
|
var _super = _createSuper(CodeNode);
|
|
@@ -120,6 +120,25 @@ export function $createCodeNode(textContent) {
|
|
|
120
120
|
export function $isCodeInlineNode(node) {
|
|
121
121
|
return node instanceof CodeNode;
|
|
122
122
|
}
|
|
123
|
+
export function getCodeInlineNode(node) {
|
|
124
|
+
if ($isCursorNode(node)) {
|
|
125
|
+
var parent = node.getParent();
|
|
126
|
+
if ($isCodeInlineNode(parent)) {
|
|
127
|
+
return parent;
|
|
128
|
+
}
|
|
129
|
+
if ($isCodeInlineNode(node.getNextSibling())) {
|
|
130
|
+
return node.getNextSibling();
|
|
131
|
+
}
|
|
132
|
+
if ($isCodeInlineNode(node.getPreviousSibling())) {
|
|
133
|
+
return node.getPreviousSibling();
|
|
134
|
+
}
|
|
135
|
+
return null;
|
|
136
|
+
}
|
|
137
|
+
if ($isCodeInlineNode(node.getParent())) {
|
|
138
|
+
return node.getParent();
|
|
139
|
+
}
|
|
140
|
+
return null;
|
|
141
|
+
}
|
|
123
142
|
export function $isSelectionInCodeInline(editor) {
|
|
124
143
|
return editor.read(function () {
|
|
125
144
|
var selection = $getSelection();
|
|
@@ -129,11 +148,11 @@ export function $isSelectionInCodeInline(editor) {
|
|
|
129
148
|
if ($isRangeSelection(selection)) {
|
|
130
149
|
var focusNode = selection.focus.getNode();
|
|
131
150
|
var anchorNode = selection.anchor.getNode();
|
|
132
|
-
|
|
151
|
+
var code = getCodeInlineNode(focusNode);
|
|
152
|
+
if (code !== getCodeInlineNode(anchorNode)) {
|
|
133
153
|
return false;
|
|
134
154
|
}
|
|
135
|
-
|
|
136
|
-
if ($isCodeInlineNode(parentNode)) {
|
|
155
|
+
if ($isCodeInlineNode(code)) {
|
|
137
156
|
return true;
|
|
138
157
|
}
|
|
139
158
|
return false;
|
|
@@ -13,10 +13,12 @@ function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.g
|
|
|
13
13
|
function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
|
|
14
14
|
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : String(i); }
|
|
15
15
|
function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
|
|
16
|
+
import { $setSelection } from 'lexical';
|
|
16
17
|
import { KernelPlugin } from "../../../editor-kernel/plugin";
|
|
18
|
+
import { $createCursorNode } from "../../common";
|
|
17
19
|
import { IMarkdownShortCutService } from "../../markdown/service/shortcut";
|
|
18
20
|
import { registerCodeInlineCommand } from "../command";
|
|
19
|
-
import { CodeNode } from "../node/code";
|
|
21
|
+
import { $createCodeNode, CodeNode } from "../node/code";
|
|
20
22
|
import { registerCodeInline } from "./registry";
|
|
21
23
|
export var CodePlugin = (_class = /*#__PURE__*/function (_KernelPlugin) {
|
|
22
24
|
_inherits(CodePlugin, _KernelPlugin);
|
|
@@ -49,6 +51,16 @@ export var CodePlugin = (_class = /*#__PURE__*/function (_KernelPlugin) {
|
|
|
49
51
|
ctx.appendLine("`".concat(node.getTextContent(), "`"));
|
|
50
52
|
return true;
|
|
51
53
|
});
|
|
54
|
+
markdownService.registerMarkdownShortCuts([{
|
|
55
|
+
process: function process(selection) {
|
|
56
|
+
var text = selection.getTextContent();
|
|
57
|
+
selection.removeText();
|
|
58
|
+
selection.insertNodes([$createCodeNode(text), $createCursorNode()]);
|
|
59
|
+
$setSelection(selection);
|
|
60
|
+
},
|
|
61
|
+
tag: '`',
|
|
62
|
+
type: 'text-format'
|
|
63
|
+
}]);
|
|
52
64
|
}
|
|
53
65
|
}]);
|
|
54
66
|
return CodePlugin;
|
|
@@ -3,6 +3,7 @@ function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o =
|
|
|
3
3
|
function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; }
|
|
4
4
|
import { mergeRegister } from '@lexical/utils';
|
|
5
5
|
import { $getNodeByKey } from 'lexical';
|
|
6
|
+
import { $createCursorNode } from "../../common";
|
|
6
7
|
import { HotkeyEnum } from "../../../types/hotkey";
|
|
7
8
|
import { INSERT_CODEINLINE_COMMAND } from "../command";
|
|
8
9
|
import { CodeNode } from "../node/code";
|
|
@@ -14,6 +15,7 @@ export function registerCodeInline(editor, kernel, options) {
|
|
|
14
15
|
var mutatedNodes = _ref2.mutatedNodes;
|
|
15
16
|
var codeChanged = mutatedNodes === null || mutatedNodes === void 0 ? void 0 : mutatedNodes.get(CodeNode);
|
|
16
17
|
var keys = (codeChanged === null || codeChanged === void 0 ? void 0 : codeChanged.keys()) || [];
|
|
18
|
+
var needAddBefore = new Set();
|
|
17
19
|
editor.read(function () {
|
|
18
20
|
var _iterator = _createForOfIteratorHelper(keys),
|
|
19
21
|
_step;
|
|
@@ -25,13 +27,8 @@ export function registerCodeInline(editor, kernel, options) {
|
|
|
25
27
|
return;
|
|
26
28
|
}
|
|
27
29
|
var parent = node.getParent();
|
|
28
|
-
if ((parent === null || parent === void 0 ? void 0 : parent.
|
|
29
|
-
|
|
30
|
-
if (!(codeElement !== null && codeElement !== void 0 && codeElement.nextSibling)) {
|
|
31
|
-
parent
|
|
32
|
-
// @ts-expect-error not error
|
|
33
|
-
.getDOMSlot(editor.getElementByKey(parent.getKey())).setManagedLineBreak('decorator');
|
|
34
|
-
}
|
|
30
|
+
if ((parent === null || parent === void 0 ? void 0 : parent.getFirstChild()) === node) {
|
|
31
|
+
needAddBefore.add(node);
|
|
35
32
|
}
|
|
36
33
|
}
|
|
37
34
|
} catch (err) {
|
|
@@ -40,6 +37,16 @@ export function registerCodeInline(editor, kernel, options) {
|
|
|
40
37
|
_iterator.f();
|
|
41
38
|
}
|
|
42
39
|
});
|
|
40
|
+
if (needAddBefore.size > 0) {
|
|
41
|
+
editor.update(function () {
|
|
42
|
+
needAddBefore.forEach(function (node) {
|
|
43
|
+
var prev = node.getPreviousSibling();
|
|
44
|
+
if (!prev) {
|
|
45
|
+
node.insertBefore($createCursorNode());
|
|
46
|
+
}
|
|
47
|
+
});
|
|
48
|
+
});
|
|
49
|
+
}
|
|
43
50
|
}), kernel.registerHotkey(HotkeyEnum.CodeInline, function () {
|
|
44
51
|
return editor.dispatchCommand(INSERT_CODEINLINE_COMMAND, undefined);
|
|
45
52
|
}, {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
export { INSERT_HEADING_COMMAND, INSERT_QUOTE_COMMAND } from './command';
|
|
2
|
-
export { $createCursorNode, $isCardLikeElementNode, CardLikeElementNode } from './node/cursor';
|
|
2
|
+
export { $createCursorNode, $isCardLikeElementNode, $isCursorNode, CardLikeElementNode, } from './node/cursor';
|
|
3
3
|
export * from './plugin';
|
|
4
4
|
export * from './react';
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
export { INSERT_HEADING_COMMAND, INSERT_QUOTE_COMMAND } from "./command";
|
|
2
|
-
export { $createCursorNode, $isCardLikeElementNode, CardLikeElementNode } from "./node/cursor";
|
|
2
|
+
export { $createCursorNode, $isCardLikeElementNode, $isCursorNode, CardLikeElementNode } from "./node/cursor";
|
|
3
3
|
export * from "./plugin";
|
|
4
4
|
export * from "./react";
|
|
@@ -130,6 +130,14 @@ export function registerCursorNode(editor) {
|
|
|
130
130
|
mutation = _step3$value[1];
|
|
131
131
|
if (mutation === 'updated') {
|
|
132
132
|
var cursorNode = $getNodeByKey(key);
|
|
133
|
+
if ((cursorNode === null || cursorNode === void 0 ? void 0 : cursorNode.getIndexWithinParent()) === 0) {
|
|
134
|
+
var nextElement = cursorNode.getNextSibling();
|
|
135
|
+
if (!$isCardLikeElementNode(nextElement) && !$isDecoratorNode(nextElement) && !$isCardLikeElementNode(cursorNode === null || cursorNode === void 0 ? void 0 : cursorNode.getParent())) {
|
|
136
|
+
needRemove.add(cursorNode);
|
|
137
|
+
} else {
|
|
138
|
+
continue;
|
|
139
|
+
}
|
|
140
|
+
}
|
|
133
141
|
var element = cursorNode === null || cursorNode === void 0 ? void 0 : cursorNode.getPreviousSibling();
|
|
134
142
|
if (!$isCardLikeElementNode(element) && !$isDecoratorNode(element) && !$isCardLikeElementNode(cursorNode === null || cursorNode === void 0 ? void 0 : cursorNode.getParent())) {
|
|
135
143
|
needRemove.add(cursorNode);
|
|
@@ -117,10 +117,6 @@ export var CommonPlugin = (_class = /*#__PURE__*/function (_KernelPlugin) {
|
|
|
117
117
|
intraword: false,
|
|
118
118
|
tag: '__',
|
|
119
119
|
type: 'text-format'
|
|
120
|
-
}, {
|
|
121
|
-
format: ['code'],
|
|
122
|
-
tag: '`',
|
|
123
|
-
type: 'text-format'
|
|
124
120
|
}, {
|
|
125
121
|
format: ['strikethrough'],
|
|
126
122
|
tag: '~~',
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
import { ElementNode, LexicalNode, TextFormatType, TextNode } from 'lexical';
|
|
1
|
+
import { ElementNode, LexicalNode, RangeSelection, TextFormatType, TextNode } from 'lexical';
|
|
2
2
|
import { IServiceID } from "../../../types/kernel";
|
|
3
3
|
export type TextFormatTransformer = Readonly<{
|
|
4
|
-
format
|
|
4
|
+
format?: ReadonlyArray<TextFormatType>;
|
|
5
5
|
intraword?: boolean;
|
|
6
|
+
process?: (selection: RangeSelection) => void;
|
|
6
7
|
tag: string;
|
|
7
8
|
type: 'text-format';
|
|
8
9
|
}>;
|
|
@@ -129,8 +130,9 @@ export declare class MarkdownShortCutService implements IMarkdownShortCutService
|
|
|
129
130
|
type: "text-match";
|
|
130
131
|
}>[]>>;
|
|
131
132
|
get textFormatTransformersByTrigger(): Readonly<Record<string, readonly Readonly<{
|
|
132
|
-
format
|
|
133
|
+
format?: readonly TextFormatType[] | undefined;
|
|
133
134
|
intraword?: boolean | undefined;
|
|
135
|
+
process?: ((selection: RangeSelection) => void) | undefined;
|
|
134
136
|
tag: string;
|
|
135
137
|
type: "text-format";
|
|
136
138
|
}>[]>>;
|
|
@@ -234,50 +234,58 @@ function $runTextFormatTransformers(anchorNode, anchorOffset, textFormatTransfor
|
|
|
234
234
|
closeNode.setTextContent(closeNodeText);
|
|
235
235
|
var openNodeText = openNode === closeNode ? closeNodeText : prevOpenNodeText;
|
|
236
236
|
openNode.setTextContent(openNodeText.slice(0, openTagStartIndex) + openNodeText.slice(openTagStartIndex + tagLength));
|
|
237
|
-
var
|
|
237
|
+
var _selection = $getSelection();
|
|
238
238
|
var nextSelection = $createRangeSelection();
|
|
239
239
|
$setSelection(nextSelection);
|
|
240
240
|
// Adjust offset based on deleted chars
|
|
241
241
|
var newOffset = closeTagEndIndex - tagLength * (openNode === closeNode ? 2 : 1) + 1;
|
|
242
242
|
nextSelection.anchor.set(openNode.__key, openTagStartIndex, 'text');
|
|
243
243
|
nextSelection.focus.set(closeNode.__key, newOffset, 'text');
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
244
|
+
if (matcher.process) {
|
|
245
|
+
matcher.process(nextSelection);
|
|
246
|
+
return true;
|
|
247
|
+
} else if (matcher.format) {
|
|
248
|
+
// Apply formatting to selected text
|
|
249
|
+
var _iterator5 = _createForOfIteratorHelper(matcher.format),
|
|
250
|
+
_step5;
|
|
251
|
+
try {
|
|
252
|
+
for (_iterator5.s(); !(_step5 = _iterator5.n()).done;) {
|
|
253
|
+
var format = _step5.value;
|
|
254
|
+
if (!nextSelection.hasFormat(format)) {
|
|
255
|
+
nextSelection.formatText(format);
|
|
256
|
+
}
|
|
253
257
|
}
|
|
254
|
-
}
|
|
255
258
|
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
259
|
+
// Collapse selection up to the focus point
|
|
260
|
+
} catch (err) {
|
|
261
|
+
_iterator5.e(err);
|
|
262
|
+
} finally {
|
|
263
|
+
_iterator5.f();
|
|
264
|
+
}
|
|
265
|
+
nextSelection.anchor.set(nextSelection.focus.key, nextSelection.focus.offset, nextSelection.focus.type);
|
|
263
266
|
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
267
|
+
// Remove formatting from collapsed selection
|
|
268
|
+
var _iterator6 = _createForOfIteratorHelper(matcher.format),
|
|
269
|
+
_step6;
|
|
270
|
+
try {
|
|
271
|
+
for (_iterator6.s(); !(_step6 = _iterator6.n()).done;) {
|
|
272
|
+
var _format = _step6.value;
|
|
273
|
+
if (nextSelection.hasFormat(_format)) {
|
|
274
|
+
nextSelection.toggleFormat(_format);
|
|
275
|
+
}
|
|
272
276
|
}
|
|
277
|
+
} catch (err) {
|
|
278
|
+
_iterator6.e(err);
|
|
279
|
+
} finally {
|
|
280
|
+
_iterator6.f();
|
|
273
281
|
}
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
282
|
+
if ($isRangeSelection(_selection)) {
|
|
283
|
+
nextSelection.format = _selection.format;
|
|
284
|
+
}
|
|
285
|
+
} else {
|
|
286
|
+
// No format or process specified, nothing to do
|
|
287
|
+
$setSelection(_selection);
|
|
288
|
+
continue;
|
|
281
289
|
}
|
|
282
290
|
return true;
|
|
283
291
|
}
|
|
@@ -15,7 +15,7 @@ function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.g
|
|
|
15
15
|
function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
|
|
16
16
|
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : String(i); }
|
|
17
17
|
function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
|
|
18
|
-
import { $getSelection, $isRangeSelection } from 'lexical';
|
|
18
|
+
import { $getSelection, $isRangeSelection, COMMAND_PRIORITY_CRITICAL, KEY_DOWN_COMMAND } from 'lexical';
|
|
19
19
|
import { KernelPlugin } from "../../../editor-kernel/plugin";
|
|
20
20
|
import { ISlashService, SlashService } from "../service/i-slash-service";
|
|
21
21
|
import { getQueryTextForSearch, tryToPositionRange } from "../utils/utils";
|
|
@@ -29,6 +29,7 @@ export var SlashPlugin = (_class = /*#__PURE__*/function (_KernelPlugin) {
|
|
|
29
29
|
_defineProperty(_assertThisInitialized(_this), "service", null);
|
|
30
30
|
_defineProperty(_assertThisInitialized(_this), "currentSlashTrigger", null);
|
|
31
31
|
_defineProperty(_assertThisInitialized(_this), "currentSlashTriggerIndex", -1);
|
|
32
|
+
_defineProperty(_assertThisInitialized(_this), "suppressOpen", false);
|
|
32
33
|
_this.config = config;
|
|
33
34
|
_this.service = new SlashService(kernel);
|
|
34
35
|
kernel.registerService(ISlashService, _this.service);
|
|
@@ -47,11 +48,23 @@ export var SlashPlugin = (_class = /*#__PURE__*/function (_KernelPlugin) {
|
|
|
47
48
|
(_this$config = this.config) === null || _this$config === void 0 || _this$config.triggerClose();
|
|
48
49
|
this.currentSlashTrigger = null;
|
|
49
50
|
this.currentSlashTriggerIndex = -1;
|
|
51
|
+
// After an explicit close, suppress reopening until next typing input
|
|
52
|
+
this.suppressOpen = true;
|
|
50
53
|
}
|
|
51
54
|
}, {
|
|
52
55
|
key: "onInit",
|
|
53
56
|
value: function onInit(editor) {
|
|
54
57
|
var _this2 = this;
|
|
58
|
+
// Reset suppression on typing-related key presses
|
|
59
|
+
this.register(editor.registerCommand(KEY_DOWN_COMMAND, function (event) {
|
|
60
|
+
if (event.isComposing) return false;
|
|
61
|
+
var key = event.key;
|
|
62
|
+
// Any character input or deletion should re-enable opening
|
|
63
|
+
if (key.length === 1 || key === 'Backspace' || key === 'Delete') {
|
|
64
|
+
_this2.suppressOpen = false;
|
|
65
|
+
}
|
|
66
|
+
return false;
|
|
67
|
+
}, COMMAND_PRIORITY_CRITICAL));
|
|
55
68
|
this.register(editor.registerUpdateListener(function () {
|
|
56
69
|
editor.getEditorState().read(function () {
|
|
57
70
|
var _this2$service, _this2$service2, _this2$service3;
|
|
@@ -79,6 +92,12 @@ export var SlashPlugin = (_class = /*#__PURE__*/function (_KernelPlugin) {
|
|
|
79
92
|
_this2.triggerClose();
|
|
80
93
|
return;
|
|
81
94
|
}
|
|
95
|
+
|
|
96
|
+
// If we previously suppressed opening, do not reopen until user types
|
|
97
|
+
if (_this2.currentSlashTrigger === null && _this2.suppressOpen) {
|
|
98
|
+
_this2.triggerClose();
|
|
99
|
+
return;
|
|
100
|
+
}
|
|
82
101
|
var triggerText = _this2.currentSlashTrigger;
|
|
83
102
|
if (triggerText === null) {
|
|
84
103
|
triggerText = text.slice(-1);
|
|
@@ -101,6 +120,14 @@ export var SlashPlugin = (_class = /*#__PURE__*/function (_KernelPlugin) {
|
|
|
101
120
|
var fuse = (_this2$service3 = _this2.service) === null || _this2$service3 === void 0 ? void 0 : _this2$service3.getSlashFuse(triggerText);
|
|
102
121
|
var isRangePositioned = tryToPositionRange(_this2.currentSlashTriggerIndex, range, editorWindow);
|
|
103
122
|
var match = triggerFn === null || triggerFn === void 0 ? void 0 : triggerFn(text.slice(_this2.currentSlashTriggerIndex));
|
|
123
|
+
|
|
124
|
+
// Check if there's a space in the current search text that should close the menu
|
|
125
|
+
var searchText = text.slice(_this2.currentSlashTriggerIndex);
|
|
126
|
+
var hasSpaceAfterTrigger = searchText.includes(' ') && !(slashOptions !== null && slashOptions !== void 0 && slashOptions.allowWhitespace);
|
|
127
|
+
if (hasSpaceAfterTrigger) {
|
|
128
|
+
_this2.triggerClose();
|
|
129
|
+
return;
|
|
130
|
+
}
|
|
104
131
|
var finalItems = fuse && match && match.matchingString.length > 0 ? fuse.search(match.matchingString).map(function (result) {
|
|
105
132
|
return result.item;
|
|
106
133
|
}) : slashOptions.items;
|
|
@@ -1,8 +1,20 @@
|
|
|
1
|
+
import type { IFuseOptions } from 'fuse.js';
|
|
1
2
|
import type { FC, ReactElement } from 'react';
|
|
2
3
|
import type { SlashOptions } from "..";
|
|
3
4
|
import type { ISlashMenuOption, ISlashOption } from "../service/i-slash-service";
|
|
4
5
|
import type { IEditor } from "../../../types";
|
|
5
6
|
export interface ReactSlashOptionProps {
|
|
7
|
+
/**
|
|
8
|
+
* Complete Fuse.js configuration options
|
|
9
|
+
* @example
|
|
10
|
+
* {
|
|
11
|
+
* keys: ['key', 'label', 'description'],
|
|
12
|
+
* threshold: 0.3,
|
|
13
|
+
* includeScore: true,
|
|
14
|
+
* includeMatches: true
|
|
15
|
+
* }
|
|
16
|
+
*/
|
|
17
|
+
fuseOptions?: IFuseOptions<ISlashMenuOption>;
|
|
6
18
|
/**
|
|
7
19
|
* Searchable options
|
|
8
20
|
*/
|
|
@@ -17,6 +29,13 @@ export interface ReactSlashOptionProps {
|
|
|
17
29
|
* Custom render component
|
|
18
30
|
*/
|
|
19
31
|
renderComp?: FC<MenuRenderProps>;
|
|
32
|
+
/**
|
|
33
|
+
* Fuse.js search keys for fuzzy matching
|
|
34
|
+
* Default is ['key']
|
|
35
|
+
* @example ['key', 'label', 'description']
|
|
36
|
+
* @deprecated Use fuseOptions instead
|
|
37
|
+
*/
|
|
38
|
+
searchKeys?: string[];
|
|
20
39
|
/**
|
|
21
40
|
* Trigger character
|
|
22
41
|
*/
|
|
@@ -1,17 +1,28 @@
|
|
|
1
1
|
import { DropdownMenuItemType } from '@lobehub/ui';
|
|
2
|
-
import Fuse from 'fuse.js';
|
|
2
|
+
import Fuse, { type IFuseOptions } from 'fuse.js';
|
|
3
3
|
import type { IEditor, IEditorKernel, IServiceID } from "../../../types";
|
|
4
4
|
import { getBasicTypeaheadTriggerMatch } from '../utils/utils';
|
|
5
5
|
export type ISlashDividerOption = {
|
|
6
6
|
type: 'divider';
|
|
7
7
|
};
|
|
8
|
-
export interface ISlashMenuOption extends
|
|
8
|
+
export interface ISlashMenuOption extends DropdownMenuItemType {
|
|
9
9
|
metadata?: Record<string, any>;
|
|
10
10
|
onSelect?: (editor: IEditor, matchingString: string) => void;
|
|
11
11
|
}
|
|
12
12
|
export type ISlashOption = ISlashMenuOption | ISlashDividerOption;
|
|
13
13
|
export interface SlashOptions {
|
|
14
14
|
allowWhitespace?: boolean;
|
|
15
|
+
/**
|
|
16
|
+
* Complete Fuse.js configuration options
|
|
17
|
+
* @example
|
|
18
|
+
* {
|
|
19
|
+
* keys: ['key', 'label', 'description'],
|
|
20
|
+
* threshold: 0.3,
|
|
21
|
+
* includeScore: true,
|
|
22
|
+
* includeMatches: true
|
|
23
|
+
* }
|
|
24
|
+
*/
|
|
25
|
+
fuseOptions?: IFuseOptions<ISlashMenuOption>;
|
|
15
26
|
items: Array<ISlashOption> | ((search: {
|
|
16
27
|
leadOffset: number;
|
|
17
28
|
matchingString: string;
|
|
@@ -20,6 +31,13 @@ export interface SlashOptions {
|
|
|
20
31
|
maxLength?: number;
|
|
21
32
|
minLength?: number;
|
|
22
33
|
punctuation?: string;
|
|
34
|
+
/**
|
|
35
|
+
* Fuse.js search keys for fuzzy matching
|
|
36
|
+
* Default is ['key']
|
|
37
|
+
* @example ['key', 'label', 'description']
|
|
38
|
+
* @deprecated Use fuseOptions instead
|
|
39
|
+
*/
|
|
40
|
+
searchKeys?: string[];
|
|
23
41
|
trigger: string;
|
|
24
42
|
}
|
|
25
43
|
export interface ISlashService {
|
|
@@ -46,9 +46,12 @@ export var SlashService = /*#__PURE__*/function () {
|
|
|
46
46
|
var searchableItems = options.items.filter(function (item) {
|
|
47
47
|
return !('type' in item) || item.type !== 'divider';
|
|
48
48
|
});
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
49
|
+
|
|
50
|
+
// Use fuseOptions if provided, otherwise fallback to searchKeys or default
|
|
51
|
+
var fuseConfig = options.fuseOptions || {
|
|
52
|
+
keys: options.searchKeys || ['key']
|
|
53
|
+
};
|
|
54
|
+
this.triggerFuseMap.set(options.trigger, new Fuse(searchableItems, fuseConfig));
|
|
52
55
|
}
|
|
53
56
|
}
|
|
54
57
|
}, {
|
|
@@ -120,14 +120,20 @@ export function getBasicTypeaheadTriggerMatch(trigger, _ref) {
|
|
|
120
120
|
_ref$allowWhitespace = _ref.allowWhitespace,
|
|
121
121
|
allowWhitespace = _ref$allowWhitespace === void 0 ? false : _ref$allowWhitespace;
|
|
122
122
|
return function (text) {
|
|
123
|
+
// When whitespace is not allowed, we need to ensure the regex stops at whitespace
|
|
123
124
|
var validCharsSuffix = allowWhitespace ? '' : '\\s';
|
|
124
125
|
var validChars = '[^' + trigger + punctuation + validCharsSuffix + ']';
|
|
125
|
-
|
|
126
|
+
|
|
127
|
+
// Create regex that matches from trigger to either end of string OR whitespace (when not allowed)
|
|
128
|
+
var regexPattern = allowWhitespace ? '(^|\\s|\\()(' + '[' + trigger + ']' + '((?:' + validChars + '){0,' + maxLength + '})' + ')$' : '(^|\\s|\\()(' + '[' + trigger + ']' + '((?:' + validChars + ')*?)' + ')(?=\\s|$)';
|
|
129
|
+
var TypeaheadTriggerRegex = new RegExp(regexPattern);
|
|
126
130
|
var match = TypeaheadTriggerRegex.exec(text);
|
|
127
131
|
if (match !== null) {
|
|
128
132
|
var maybeLeadingWhitespace = match[1];
|
|
129
133
|
var matchingString = match[3];
|
|
130
|
-
|
|
134
|
+
|
|
135
|
+
// Check length constraints
|
|
136
|
+
if (matchingString.length >= minLength && matchingString.length <= maxLength) {
|
|
131
137
|
return {
|
|
132
138
|
leadOffset: match.index + maybeLeadingWhitespace.length,
|
|
133
139
|
matchingString: matchingString,
|
|
@@ -3,5 +3,5 @@ function _taggedTemplateLiteral(strings, raw) { if (!raw) { raw = strings.slice(
|
|
|
3
3
|
import { createStyles } from 'antd-style';
|
|
4
4
|
export var useStyles = createStyles(function (_ref) {
|
|
5
5
|
var css = _ref.css;
|
|
6
|
-
return css(_templateObject || (_templateObject = _taggedTemplateLiteral(["\n will-change: transform;\n\n position: absolute;\n z-index: 3;\n inset-block-start: 0;\n inset-inline-start: 0;\n "])));
|
|
6
|
+
return css(_templateObject || (_templateObject = _taggedTemplateLiteral(["\n will-change: transform;\n\n position: absolute;\n z-index: 3;\n inset-block-start: 0;\n inset-inline-start: 0;\n\n background: red;\n "])));
|
|
7
7
|
});
|
|
@@ -19,7 +19,7 @@ import { PlusIcon } from 'lucide-react';
|
|
|
19
19
|
import { memo, useEffect, useMemo, useRef, useState } from 'react';
|
|
20
20
|
import { createPortal } from 'react-dom';
|
|
21
21
|
import { useLexicalComposerContext } from "../../../../editor-kernel/react";
|
|
22
|
-
import {
|
|
22
|
+
import { useStyles } from "./style";
|
|
23
23
|
import { getMouseInfo, useDebounce } from "./utils";
|
|
24
24
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
25
25
|
import { jsxs as _jsxs } from "react/jsx-runtime";
|
|
@@ -94,12 +94,10 @@ var TableHoverActionsContainer = /*#__PURE__*/memo(function (_ref) {
|
|
|
94
94
|
});
|
|
95
95
|
if (tableDOMElement) {
|
|
96
96
|
var _getBoundingClientRec = tableDOMElement.getBoundingClientRect(),
|
|
97
|
-
tableElemWidth = _getBoundingClientRec.width,
|
|
98
97
|
tableElemY = _getBoundingClientRec.y,
|
|
99
98
|
tableElemRight = _getBoundingClientRec.right,
|
|
100
99
|
tableElemLeft = _getBoundingClientRec.left,
|
|
101
|
-
tableElemBottom = _getBoundingClientRec.bottom
|
|
102
|
-
tableElemHeight = _getBoundingClientRec.height;
|
|
100
|
+
tableElemBottom = _getBoundingClientRec.bottom;
|
|
103
101
|
|
|
104
102
|
// Adjust for using the scrollable table container
|
|
105
103
|
var parentElement = tableDOMElement.parentElement;
|
|
@@ -114,19 +112,15 @@ var TableHoverActionsContainer = /*#__PURE__*/memo(function (_ref) {
|
|
|
114
112
|
setShownColumn(false);
|
|
115
113
|
setShownRow(true);
|
|
116
114
|
setPosition({
|
|
117
|
-
height: BUTTON_WIDTH_PX,
|
|
118
115
|
left: tableHasScroll && parentElement ? parentElement.offsetLeft : tableElemLeft - editorElemLeft,
|
|
119
|
-
top: tableElemBottom - editorElemY + 5
|
|
120
|
-
width: tableHasScroll && parentElement ? parentElement.offsetWidth : tableElemWidth
|
|
116
|
+
top: tableElemBottom - editorElemY + 5
|
|
121
117
|
});
|
|
122
118
|
} else if (hoveredColumnNode) {
|
|
123
119
|
setShownColumn(true);
|
|
124
120
|
setShownRow(false);
|
|
125
121
|
setPosition({
|
|
126
|
-
height: tableElemHeight,
|
|
127
122
|
left: tableElemRight - editorElemLeft + 5,
|
|
128
|
-
top: tableElemY - editorElemY
|
|
129
|
-
width: BUTTON_WIDTH_PX
|
|
123
|
+
top: tableElemY - editorElemY
|
|
130
124
|
});
|
|
131
125
|
}
|
|
132
126
|
}
|
|
@@ -5,7 +5,7 @@ export var BUTTON_WIDTH_PX = 20;
|
|
|
5
5
|
export var useStyles = createStyles(function (_ref) {
|
|
6
6
|
var css = _ref.css;
|
|
7
7
|
return {
|
|
8
|
-
tableAddColumns: css(_templateObject || (_templateObject = _taggedTemplateLiteral(["\n position: absolute;\n
|
|
9
|
-
tableAddRows: css(_templateObject2 || (_templateObject2 = _taggedTemplateLiteral(["\n position: absolute;\n
|
|
8
|
+
tableAddColumns: css(_templateObject || (_templateObject = _taggedTemplateLiteral(["\n position: absolute;\n "]))),
|
|
9
|
+
tableAddRows: css(_templateObject2 || (_templateObject2 = _taggedTemplateLiteral(["\n position: absolute;\n "])))
|
|
10
10
|
};
|
|
11
11
|
});
|
|
@@ -1,50 +1,152 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
|
|
3
3
|
function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
|
|
4
|
-
var _excluded = ["maxHeight", "className", "children", "footer", "header", "style", "slashMenuRef", "classNames", "fullscreen", "styles"];
|
|
4
|
+
var _excluded = ["defaultHeight", "height", "maxHeight", "minHeight", "resizeMaxHeightOffset", "resize", "onSizeChange", "onSizeDragging", "className", "children", "footer", "header", "style", "slashMenuRef", "classNames", "fullscreen", "showResizeHandle", "styles"];
|
|
5
5
|
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
|
|
6
6
|
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
|
|
7
7
|
function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
|
|
8
8
|
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : String(i); }
|
|
9
9
|
function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
|
|
10
|
+
function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
|
|
11
|
+
function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
|
|
12
|
+
function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
|
|
13
|
+
function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; }
|
|
14
|
+
function _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (null != t) { var e, n, i, u, a = [], f = !0, o = !1; try { if (i = (t = t.call(r)).next, 0 === l) { if (Object(t) !== t) return; f = !1; } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0); } catch (r) { o = !0, n = r; } finally { try { if (!f && null != t.return && (u = t.return(), Object(u) !== u)) return; } finally { if (o) throw n; } } return a; } }
|
|
15
|
+
function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
|
|
10
16
|
function _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }
|
|
11
17
|
function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }
|
|
12
|
-
import {
|
|
18
|
+
import { Resizable } from 're-resizable';
|
|
19
|
+
import { memo, useCallback } from 'react';
|
|
13
20
|
import { Flexbox } from 'react-layout-kit';
|
|
21
|
+
import useMergeState from 'use-merge-value';
|
|
22
|
+
import { useHeight } from "../hooks/useSize";
|
|
14
23
|
import { useStyles } from "./style";
|
|
15
24
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
16
25
|
import { jsxs as _jsxs } from "react/jsx-runtime";
|
|
17
|
-
var ChatInput = /*#__PURE__*/memo(function (
|
|
18
|
-
var
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
26
|
+
var ChatInput = /*#__PURE__*/memo(function (props) {
|
|
27
|
+
var _props$defaultHeight = props.defaultHeight,
|
|
28
|
+
defaultHeight = _props$defaultHeight === void 0 ? props.defaultHeight || props.minHeight || 64 : _props$defaultHeight,
|
|
29
|
+
height = props.height,
|
|
30
|
+
_props$maxHeight = props.maxHeight,
|
|
31
|
+
maxHeight = _props$maxHeight === void 0 ? 320 : _props$maxHeight,
|
|
32
|
+
_props$minHeight = props.minHeight,
|
|
33
|
+
minHeight = _props$minHeight === void 0 ? 64 : _props$minHeight,
|
|
34
|
+
_props$resizeMaxHeigh = props.resizeMaxHeightOffset,
|
|
35
|
+
resizeMaxHeightOffset = _props$resizeMaxHeigh === void 0 ? 120 : _props$resizeMaxHeigh,
|
|
36
|
+
_props$resize = props.resize,
|
|
37
|
+
resize = _props$resize === void 0 ? true : _props$resize,
|
|
38
|
+
onSizeChange = props.onSizeChange,
|
|
39
|
+
onSizeDragging = props.onSizeDragging,
|
|
40
|
+
className = props.className,
|
|
41
|
+
children = props.children,
|
|
42
|
+
footer = props.footer,
|
|
43
|
+
header = props.header,
|
|
44
|
+
style = props.style,
|
|
45
|
+
slashMenuRef = props.slashMenuRef,
|
|
46
|
+
classNames = props.classNames,
|
|
47
|
+
fullscreen = props.fullscreen,
|
|
48
|
+
showResizeHandle = props.showResizeHandle,
|
|
49
|
+
customStyles = props.styles,
|
|
50
|
+
rest = _objectWithoutProperties(props, _excluded);
|
|
30
51
|
var _useStyles = useStyles(),
|
|
31
52
|
cx = _useStyles.cx,
|
|
32
53
|
styles = _useStyles.styles;
|
|
54
|
+
var _useHeight = useHeight(),
|
|
55
|
+
headerRef = _useHeight.ref,
|
|
56
|
+
_useHeight$height = _useHeight.height,
|
|
57
|
+
headerHeight = _useHeight$height === void 0 ? 0 : _useHeight$height;
|
|
58
|
+
|
|
59
|
+
// 使用 useMergeState 管理高度状态
|
|
60
|
+
var _useMergeState = useMergeState(defaultHeight, {
|
|
61
|
+
defaultValue: defaultHeight,
|
|
62
|
+
onChange: onSizeChange,
|
|
63
|
+
value: height
|
|
64
|
+
}),
|
|
65
|
+
_useMergeState2 = _slicedToArray(_useMergeState, 2),
|
|
66
|
+
currentHeight = _useMergeState2[0],
|
|
67
|
+
setCurrentHeight = _useMergeState2[1];
|
|
68
|
+
|
|
69
|
+
// 处理尺寸变化
|
|
70
|
+
var handleResizeStop = useCallback(function (e, direction, ref) {
|
|
71
|
+
var newHeight = ref.style.height ? parseInt(ref.style.height) : defaultHeight;
|
|
72
|
+
setCurrentHeight(newHeight);
|
|
73
|
+
}, [setCurrentHeight, defaultHeight]);
|
|
74
|
+
|
|
75
|
+
// 处理拖拽过程中的尺寸变化
|
|
76
|
+
var handleResize = useCallback(function (e, direction, ref) {
|
|
77
|
+
var newHeight = ref.style.height ? parseInt(ref.style.height) : defaultHeight;
|
|
78
|
+
onSizeDragging === null || onSizeDragging === void 0 || onSizeDragging(newHeight);
|
|
79
|
+
}, [onSizeDragging, defaultHeight]);
|
|
80
|
+
var bodyNode = /*#__PURE__*/_jsx("div", {
|
|
81
|
+
className: cx(styles.editor, classNames === null || classNames === void 0 ? void 0 : classNames.body),
|
|
82
|
+
style: _objectSpread(_objectSpread({}, customStyles === null || customStyles === void 0 ? void 0 : customStyles.body), {}, {
|
|
83
|
+
flex: 1,
|
|
84
|
+
maxHeight: fullscreen ? '100%' : maxHeight,
|
|
85
|
+
minHeight: resize ? currentHeight : minHeight,
|
|
86
|
+
zIndex: 0
|
|
87
|
+
}),
|
|
88
|
+
children: children
|
|
89
|
+
});
|
|
33
90
|
return /*#__PURE__*/_jsxs(Flexbox, _objectSpread(_objectSpread({
|
|
34
91
|
className: cx(styles.container, className),
|
|
35
92
|
height: fullscreen ? '100%' : undefined,
|
|
36
93
|
style: _objectSpread({
|
|
37
|
-
|
|
94
|
+
position: 'relative'
|
|
38
95
|
}, style),
|
|
39
|
-
width:
|
|
96
|
+
width: "100%"
|
|
40
97
|
}, rest), {}, {
|
|
41
98
|
children: [slashMenuRef && /*#__PURE__*/_jsx("div", {
|
|
42
99
|
ref: slashMenuRef
|
|
43
|
-
}),
|
|
44
|
-
className:
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
100
|
+
}), /*#__PURE__*/_jsx("div", {
|
|
101
|
+
className: classNames === null || classNames === void 0 ? void 0 : classNames.header,
|
|
102
|
+
ref: headerRef,
|
|
103
|
+
style: _objectSpread({
|
|
104
|
+
width: '100%',
|
|
105
|
+
zIndex: 1
|
|
106
|
+
}, customStyles === null || customStyles === void 0 ? void 0 : customStyles.header),
|
|
107
|
+
children: header
|
|
108
|
+
}), resize ? /*#__PURE__*/_jsx(Resizable, {
|
|
109
|
+
className: styles.resizableContainer,
|
|
110
|
+
enable: fullscreen ? false : {
|
|
111
|
+
top: true
|
|
112
|
+
},
|
|
113
|
+
handleClasses: {
|
|
114
|
+
top: showResizeHandle ? styles.resizeHandle : undefined
|
|
115
|
+
},
|
|
116
|
+
handleStyles: {
|
|
117
|
+
top: {
|
|
118
|
+
backgroundColor: 'transparent',
|
|
119
|
+
borderRadius: '4px',
|
|
120
|
+
cursor: 'ns-resize',
|
|
121
|
+
height: '8px',
|
|
122
|
+
left: '50%',
|
|
123
|
+
top: !!header ? -3 - headerHeight : -3,
|
|
124
|
+
transform: 'translateX(-50%)',
|
|
125
|
+
width: '100%'
|
|
126
|
+
}
|
|
127
|
+
},
|
|
128
|
+
maxHeight: fullscreen ? undefined : maxHeight + resizeMaxHeightOffset,
|
|
129
|
+
minHeight: fullscreen ? undefined : minHeight,
|
|
130
|
+
onResize: handleResize,
|
|
131
|
+
onResizeStop: handleResizeStop,
|
|
132
|
+
size: {
|
|
133
|
+
height: fullscreen ? undefined : 'auto',
|
|
134
|
+
width: '100%'
|
|
135
|
+
},
|
|
136
|
+
style: fullscreen ? {
|
|
137
|
+
flex: 1,
|
|
138
|
+
overflow: 'hidden',
|
|
139
|
+
position: 'relative'
|
|
140
|
+
} : {},
|
|
141
|
+
children: bodyNode
|
|
142
|
+
}) : bodyNode, /*#__PURE__*/_jsx("div", {
|
|
143
|
+
className: classNames === null || classNames === void 0 ? void 0 : classNames.footer,
|
|
144
|
+
style: _objectSpread({
|
|
145
|
+
width: '100%',
|
|
146
|
+
zIndex: 1
|
|
147
|
+
}, customStyles === null || customStyles === void 0 ? void 0 : customStyles.footer),
|
|
148
|
+
children: footer
|
|
149
|
+
})]
|
|
48
150
|
}));
|
|
49
151
|
});
|
|
50
152
|
ChatInput.displayName = 'ChatInput';
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
export declare const useStyles: (props?: unknown) => import("antd-style").ReturnStyles<{
|
|
2
2
|
container: import("antd-style").SerializedStyles;
|
|
3
3
|
editor: import("antd-style").SerializedStyles;
|
|
4
|
+
resizableContainer: import("antd-style").SerializedStyles;
|
|
5
|
+
resizeHandle: import("antd-style").SerializedStyles;
|
|
4
6
|
}>;
|
|
@@ -1,11 +1,13 @@
|
|
|
1
|
-
var _templateObject, _templateObject2;
|
|
1
|
+
var _templateObject, _templateObject2, _templateObject3, _templateObject4;
|
|
2
2
|
function _taggedTemplateLiteral(strings, raw) { if (!raw) { raw = strings.slice(0); } return Object.freeze(Object.defineProperties(strings, { raw: { value: Object.freeze(raw) } })); }
|
|
3
3
|
import { createStyles } from 'antd-style';
|
|
4
4
|
export var useStyles = createStyles(function (_ref) {
|
|
5
5
|
var css = _ref.css,
|
|
6
6
|
token = _ref.token;
|
|
7
7
|
return {
|
|
8
|
-
container: css(_templateObject || (_templateObject = _taggedTemplateLiteral(["\n position: relative;\n\n border: 1px solid ", ";\n border-radius: ", "px;\n\n background-color: ", ";\n box-shadow:\n ", ",\n 0 32px 0 ", ";\n "])), token.colorBorderSecondary, token.borderRadiusLG, token.colorBgContainer, token.boxShadowTertiary, token.colorBgContainerSecondary),
|
|
9
|
-
editor: css(_templateObject2 || (_templateObject2 = _taggedTemplateLiteral(["\n overflow: hidden auto;\n flex: 1;\n\n width: 100%;\n padding-block: 8px 0;\n padding-inline: 12px;\n "])))
|
|
8
|
+
container: css(_templateObject || (_templateObject = _taggedTemplateLiteral(["\n position: relative;\n\n display: flex;\n flex-direction: column;\n\n height: 100%;\n border: 1px solid ", ";\n border-radius: ", "px;\n\n background-color: ", ";\n box-shadow:\n ", ",\n 0 32px 0 ", ";\n "])), token.colorBorderSecondary, token.borderRadiusLG, token.colorBgContainer, token.boxShadowTertiary, token.colorBgContainerSecondary),
|
|
9
|
+
editor: css(_templateObject2 || (_templateObject2 = _taggedTemplateLiteral(["\n overflow: hidden auto;\n flex: 1;\n\n width: 100%;\n padding-block: 8px 0;\n padding-inline: 12px;\n "]))),
|
|
10
|
+
resizableContainer: css(_templateObject3 || (_templateObject3 = _taggedTemplateLiteral(["\n position: relative;\n\n display: flex;\n flex-direction: column;\n align-self: flex-end;\n\n width: 100%;\n\n &:hover .resize-handle {\n opacity: 1;\n }\n "]))),
|
|
11
|
+
resizeHandle: css(_templateObject4 || (_templateObject4 = _taggedTemplateLiteral(["\n position: absolute;\n inset-block-start: -4px;\n inset-inline-start: 50%;\n transform: translateX(-50%);\n\n width: 100%;\n height: 8px;\n\n opacity: 0;\n\n transition: opacity 0.2s ease-in-out;\n\n &::before {\n content: '';\n\n position: absolute;\n inset-block-start: 0;\n inset-inline-start: 50%;\n transform: translateX(-50%);\n\n width: 32px;\n height: 4px;\n border-radius: 4px;\n\n background-color: ", ";\n box-shadow: 0 1px 2px ", "20;\n }\n\n &:hover {\n opacity: 1 !important;\n\n &::before {\n background-color: ", ";\n box-shadow: 0 2px 4px ", "40;\n }\n }\n\n &:active {\n &::before {\n background-color: ", ";\n }\n }\n "])), token.colorPrimary, token.colorTextSecondary, token.colorPrimaryHover, token.colorTextSecondary, token.colorPrimaryActive)
|
|
10
12
|
};
|
|
11
13
|
});
|
|
@@ -1,15 +1,27 @@
|
|
|
1
1
|
import type { CSSProperties, ReactNode, Ref } from 'react';
|
|
2
2
|
import { FlexboxProps } from 'react-layout-kit';
|
|
3
|
-
export interface ChatInputProps extends FlexboxProps {
|
|
3
|
+
export interface ChatInputProps extends Omit<FlexboxProps, 'height'> {
|
|
4
4
|
classNames?: {
|
|
5
5
|
body?: string;
|
|
6
|
+
footer?: string;
|
|
7
|
+
header?: string;
|
|
6
8
|
};
|
|
9
|
+
defaultHeight?: number;
|
|
7
10
|
footer?: ReactNode;
|
|
8
11
|
fullscreen?: boolean;
|
|
9
12
|
header?: ReactNode;
|
|
10
|
-
|
|
13
|
+
height?: number;
|
|
14
|
+
maxHeight?: number;
|
|
15
|
+
minHeight?: number;
|
|
16
|
+
onSizeChange?: (height: number) => void;
|
|
17
|
+
onSizeDragging?: (height: number) => void;
|
|
18
|
+
resize?: boolean;
|
|
19
|
+
resizeMaxHeightOffset?: number;
|
|
20
|
+
showResizeHandle?: boolean;
|
|
11
21
|
slashMenuRef?: Ref<HTMLDivElement>;
|
|
12
22
|
styles?: {
|
|
13
23
|
body?: CSSProperties;
|
|
24
|
+
footer?: CSSProperties;
|
|
25
|
+
header?: CSSProperties;
|
|
14
26
|
};
|
|
15
27
|
}
|
|
@@ -8,6 +8,6 @@ interface UseDisplayActionCountOptions {
|
|
|
8
8
|
export declare const useDisplayActionCount: ({ items, collapseOffset, autoCollapse, }?: UseDisplayActionCountOptions) => {
|
|
9
9
|
collapsed: boolean;
|
|
10
10
|
maxCount: number;
|
|
11
|
-
ref: import("react").RefObject<
|
|
11
|
+
ref: import("react").RefObject<HTMLDivElement | null>;
|
|
12
12
|
};
|
|
13
13
|
export {};
|
|
@@ -5,7 +5,7 @@ function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len
|
|
|
5
5
|
function _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (null != t) { var e, n, i, u, a = [], f = !0, o = !1; try { if (i = (t = t.call(r)).next, 0 === l) { if (Object(t) !== t) return; f = !1; } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0); } catch (r) { o = !0, n = r; } finally { try { if (!f && null != t.return && (u = t.return(), Object(u) !== u)) return; } finally { if (o) throw n; } } return a; } }
|
|
6
6
|
function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
|
|
7
7
|
import { useEffect, useMemo, useState } from 'react';
|
|
8
|
-
import {
|
|
8
|
+
import { useWidth } from "../../hooks/useSize";
|
|
9
9
|
export var useDisplayActionCount = function useDisplayActionCount() {
|
|
10
10
|
var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},
|
|
11
11
|
_ref$items = _ref.items,
|
|
@@ -13,9 +13,9 @@ export var useDisplayActionCount = function useDisplayActionCount() {
|
|
|
13
13
|
_ref$collapseOffset = _ref.collapseOffset,
|
|
14
14
|
collapseOffset = _ref$collapseOffset === void 0 ? 0 : _ref$collapseOffset,
|
|
15
15
|
autoCollapse = _ref.autoCollapse;
|
|
16
|
-
var
|
|
17
|
-
ref =
|
|
18
|
-
|
|
16
|
+
var _useWidth = useWidth(),
|
|
17
|
+
ref = _useWidth.ref,
|
|
18
|
+
width = _useWidth.width;
|
|
19
19
|
var _useState = useState(false),
|
|
20
20
|
_useState2 = _slicedToArray(_useState, 2),
|
|
21
21
|
collapsed = _useState2[0],
|
|
@@ -48,14 +48,14 @@ export var useDisplayActionCount = function useDisplayActionCount() {
|
|
|
48
48
|
setMaxCount(rawMaxCount);
|
|
49
49
|
return;
|
|
50
50
|
}
|
|
51
|
-
if (!
|
|
51
|
+
if (!width) return;
|
|
52
52
|
var atLeastCount = 1 + alwaysDisplayCount;
|
|
53
|
-
var calcMaxCount = Math.floor((
|
|
53
|
+
var calcMaxCount = Math.floor((width - collapseOffset) / 38);
|
|
54
54
|
if (calcMaxCount < atLeastCount) calcMaxCount = atLeastCount;
|
|
55
55
|
setCollapsed(calcMaxCount < rawMaxCount);
|
|
56
56
|
if (calcMaxCount >= rawMaxCount) return;
|
|
57
57
|
setMaxCount(calcMaxCount);
|
|
58
|
-
}, [autoCollapse,
|
|
58
|
+
}, [autoCollapse, width, rawMaxCount, collapseOffset, alwaysDisplayCount]);
|
|
59
59
|
return useMemo(function () {
|
|
60
60
|
return {
|
|
61
61
|
collapsed: collapsed,
|
|
@@ -71,10 +71,10 @@ var Editor = /*#__PURE__*/memo(function (_ref) {
|
|
|
71
71
|
if (!enableSlash && !enableMention) return null;
|
|
72
72
|
return /*#__PURE__*/_jsxs(ReactSlashPlugin, {
|
|
73
73
|
children: [enableSlash ? /*#__PURE__*/_jsx(ReactSlashOption, _objectSpread({
|
|
74
|
-
maxLength:
|
|
74
|
+
maxLength: 8,
|
|
75
75
|
trigger: "/"
|
|
76
76
|
}, slashOption)) : undefined, enableMention ? /*#__PURE__*/_jsx(ReactSlashOption, _objectSpread({
|
|
77
|
-
maxLength:
|
|
77
|
+
maxLength: 8,
|
|
78
78
|
trigger: "@"
|
|
79
79
|
}, restMentionOption)) : undefined]
|
|
80
80
|
});
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/// <reference types="react" />
|
|
2
|
+
interface UseContainerSizeOptions {
|
|
3
|
+
debounceMs?: number;
|
|
4
|
+
}
|
|
5
|
+
export declare const useWidth: (options?: UseContainerSizeOptions) => {
|
|
6
|
+
ref: import("react").RefObject<HTMLDivElement | null>;
|
|
7
|
+
width: number | undefined;
|
|
8
|
+
};
|
|
9
|
+
export declare const useHeight: (options?: UseContainerSizeOptions) => {
|
|
10
|
+
height: number | undefined;
|
|
11
|
+
ref: import("react").RefObject<HTMLDivElement | null>;
|
|
12
|
+
};
|
|
13
|
+
export {};
|
|
@@ -7,7 +7,7 @@ function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
|
|
|
7
7
|
// hooks/useContainerSize.ts
|
|
8
8
|
import { debounce } from 'lodash-es';
|
|
9
9
|
import { useCallback, useEffect, useRef, useState } from 'react';
|
|
10
|
-
export var
|
|
10
|
+
export var useWidth = function useWidth() {
|
|
11
11
|
var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
|
|
12
12
|
var _options$debounceMs = options.debounceMs,
|
|
13
13
|
debounceMs = _options$debounceMs === void 0 ? 100 : _options$debounceMs;
|
|
@@ -32,12 +32,46 @@ export var useContainerSize = function useContainerSize() {
|
|
|
32
32
|
if (resizeObserverRef.current) {
|
|
33
33
|
var _updateSize$cancel;
|
|
34
34
|
resizeObserverRef.current.disconnect();
|
|
35
|
-
(_updateSize$cancel = updateSize.cancel) === null || _updateSize$cancel === void 0 || _updateSize$cancel.call(updateSize);
|
|
35
|
+
(_updateSize$cancel = updateSize.cancel) === null || _updateSize$cancel === void 0 || _updateSize$cancel.call(updateSize);
|
|
36
36
|
}
|
|
37
37
|
};
|
|
38
38
|
}, [updateSize]);
|
|
39
39
|
return {
|
|
40
40
|
ref: ref,
|
|
41
|
-
|
|
41
|
+
width: size
|
|
42
|
+
};
|
|
43
|
+
};
|
|
44
|
+
export var useHeight = function useHeight() {
|
|
45
|
+
var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
|
|
46
|
+
var _options$debounceMs2 = options.debounceMs,
|
|
47
|
+
debounceMs = _options$debounceMs2 === void 0 ? 100 : _options$debounceMs2;
|
|
48
|
+
var ref = useRef(null);
|
|
49
|
+
var _useState3 = useState(),
|
|
50
|
+
_useState4 = _slicedToArray(_useState3, 2),
|
|
51
|
+
size = _useState4[0],
|
|
52
|
+
setSize = _useState4[1];
|
|
53
|
+
var resizeObserverRef = useRef(null);
|
|
54
|
+
var updateSize = useCallback(debounce(function (entries) {
|
|
55
|
+
if (entries[0]) {
|
|
56
|
+
var height = entries[0].contentRect.height;
|
|
57
|
+
setSize(Math.floor(height));
|
|
58
|
+
}
|
|
59
|
+
}, debounceMs), [debounceMs]);
|
|
60
|
+
useEffect(function () {
|
|
61
|
+
var element = ref.current;
|
|
62
|
+
if (!element) return;
|
|
63
|
+
resizeObserverRef.current = new ResizeObserver(updateSize);
|
|
64
|
+
resizeObserverRef.current.observe(element);
|
|
65
|
+
return function () {
|
|
66
|
+
if (resizeObserverRef.current) {
|
|
67
|
+
var _updateSize$cancel2;
|
|
68
|
+
resizeObserverRef.current.disconnect();
|
|
69
|
+
(_updateSize$cancel2 = updateSize.cancel) === null || _updateSize$cancel2 === void 0 || _updateSize$cancel2.call(updateSize);
|
|
70
|
+
}
|
|
71
|
+
};
|
|
72
|
+
}, [updateSize]);
|
|
73
|
+
return {
|
|
74
|
+
height: size,
|
|
75
|
+
ref: ref
|
|
42
76
|
};
|
|
43
77
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lobehub/editor",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.8.0",
|
|
4
4
|
"description": "A powerful and extensible rich text editor built on Meta's Lexical framework, providing a modern editing experience with React integration.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"lobehub",
|
|
@@ -52,6 +52,7 @@
|
|
|
52
52
|
"lodash-es": "^4.17.21",
|
|
53
53
|
"lucide-react": "^0.536.0",
|
|
54
54
|
"polished": "^4.3.1",
|
|
55
|
+
"re-resizable": "^6.11.2",
|
|
55
56
|
"react-error-boundary": "^6.0.0",
|
|
56
57
|
"react-layout-kit": "^2.0.0",
|
|
57
58
|
"react-merge-refs": "^3.0.2",
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
/// <reference types="react" />
|
|
2
|
-
interface UseContainerSizeOptions {
|
|
3
|
-
debounceMs?: number;
|
|
4
|
-
}
|
|
5
|
-
export declare const useContainerSize: (options?: UseContainerSizeOptions) => {
|
|
6
|
-
ref: import("react").RefObject<HTMLElement | null>;
|
|
7
|
-
size: number | undefined;
|
|
8
|
-
};
|
|
9
|
-
export {};
|