@ai-group/chat-sdk 3.7.1-alpha3 → 3.7.1-alpha5
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/cjs/components/FileGallery/styles.js +21 -1
- package/dist/cjs/components/FileGallery/styles.js.map +2 -2
- package/dist/cjs/components/XAdkChatbot/components/MarkdownRender/index.d.ts +9 -1
- package/dist/cjs/components/XAdkChatbot/components/MarkdownRender/index.js +102 -22
- package/dist/cjs/components/XAdkChatbot/components/MarkdownRender/index.js.map +2 -2
- package/dist/cjs/components/XAdkChatbot/components/MarkdownRender/styles.d.ts +3 -0
- package/dist/cjs/components/XAdkChatbot/components/MarkdownRender/styles.js +39 -0
- package/dist/cjs/components/XAdkChatbot/components/MarkdownRender/styles.js.map +2 -2
- package/dist/cjs/components/XAdkChatbot/index.js +42 -5
- package/dist/cjs/components/XAdkChatbot/index.js.map +2 -2
- package/dist/cjs/components/XAdkChatbot/styles.js +1 -1
- package/dist/cjs/components/XAdkChatbot/styles.js.map +1 -1
- package/dist/cjs/components/XAdkSender/InlineTagInput.d.ts +11 -5
- package/dist/cjs/components/XAdkSender/InlineTagInput.js +119 -77
- package/dist/cjs/components/XAdkSender/InlineTagInput.js.map +2 -2
- package/dist/cjs/components/XAdkSender/InputTags.d.ts +2 -2
- package/dist/cjs/components/XAdkSender/InputTags.js +8 -8
- package/dist/cjs/components/XAdkSender/InputTags.js.map +2 -2
- package/dist/cjs/components/XAdkSender/index.js +73 -45
- package/dist/cjs/components/XAdkSender/index.js.map +2 -2
- package/dist/cjs/index.d.ts +2 -1
- package/dist/cjs/index.js +7 -0
- package/dist/cjs/index.js.map +2 -2
- package/dist/cjs/presets/xgroup/preset.js +2 -1
- package/dist/cjs/presets/xgroup/preset.js.map +2 -2
- package/dist/cjs/presets/xgroup/strategies.d.ts +5 -1
- package/dist/cjs/presets/xgroup/strategies.js +16 -1
- package/dist/cjs/presets/xgroup/strategies.js.map +3 -3
- package/dist/cjs/types/ChatStrategies.d.ts +5 -0
- package/dist/cjs/types/ChatStrategies.js.map +1 -1
- package/dist/cjs/types/XAdkChatbot.d.ts +15 -0
- package/dist/cjs/types/XAdkChatbot.js.map +1 -1
- package/dist/cjs/types/XAdkSender.d.ts +62 -24
- package/dist/cjs/types/XAdkSender.js.map +1 -1
- package/dist/cjs/utils/index.d.ts +1 -0
- package/dist/cjs/utils/index.js +3 -1
- package/dist/cjs/utils/index.js.map +2 -2
- package/dist/cjs/utils/markdownResource.d.ts +11 -0
- package/dist/cjs/utils/markdownResource.js +79 -0
- package/dist/cjs/utils/markdownResource.js.map +7 -0
- package/dist/esm/components/FileGallery/styles.js +2 -2
- package/dist/esm/components/FileGallery/styles.js.map +1 -1
- package/dist/esm/components/XAdkChatbot/components/MarkdownRender/index.d.ts +9 -1
- package/dist/esm/components/XAdkChatbot/components/MarkdownRender/index.js +64 -7
- package/dist/esm/components/XAdkChatbot/components/MarkdownRender/index.js.map +1 -1
- package/dist/esm/components/XAdkChatbot/components/MarkdownRender/styles.d.ts +3 -0
- package/dist/esm/components/XAdkChatbot/components/MarkdownRender/styles.js +5 -2
- package/dist/esm/components/XAdkChatbot/components/MarkdownRender/styles.js.map +1 -1
- package/dist/esm/components/XAdkChatbot/index.js +25 -6
- package/dist/esm/components/XAdkChatbot/index.js.map +1 -1
- package/dist/esm/components/XAdkChatbot/styles.js +1 -1
- package/dist/esm/components/XAdkChatbot/styles.js.map +1 -1
- package/dist/esm/components/XAdkSender/InlineTagInput.d.ts +11 -5
- package/dist/esm/components/XAdkSender/InlineTagInput.js +125 -97
- package/dist/esm/components/XAdkSender/InlineTagInput.js.map +1 -1
- package/dist/esm/components/XAdkSender/InputTags.d.ts +2 -2
- package/dist/esm/components/XAdkSender/InputTags.js +9 -9
- package/dist/esm/components/XAdkSender/InputTags.js.map +1 -1
- package/dist/esm/components/XAdkSender/index.js +97 -71
- package/dist/esm/components/XAdkSender/index.js.map +1 -1
- package/dist/esm/index.d.ts +2 -1
- package/dist/esm/index.js +2 -1
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/presets/xgroup/preset.js +3 -2
- package/dist/esm/presets/xgroup/preset.js.map +1 -1
- package/dist/esm/presets/xgroup/strategies.d.ts +5 -1
- package/dist/esm/presets/xgroup/strategies.js +12 -1
- package/dist/esm/presets/xgroup/strategies.js.map +1 -1
- package/dist/esm/types/ChatStrategies.d.ts +5 -0
- package/dist/esm/types/ChatStrategies.js.map +1 -1
- package/dist/esm/types/XAdkChatbot.d.ts +15 -0
- package/dist/esm/types/XAdkChatbot.js.map +1 -1
- package/dist/esm/types/XAdkSender.d.ts +62 -24
- package/dist/esm/types/XAdkSender.js.map +1 -1
- package/dist/esm/utils/index.d.ts +1 -0
- package/dist/esm/utils/index.js +1 -0
- package/dist/esm/utils/index.js.map +1 -1
- package/dist/esm/utils/markdownResource.d.ts +11 -0
- package/dist/esm/utils/markdownResource.js +36 -0
- package/dist/esm/utils/markdownResource.js.map +1 -0
- package/dist/umd/chat-sdk.min.js +1 -1
- package/package.json +1 -1
|
@@ -5,8 +5,8 @@ import { useStyles } from "./styles";
|
|
|
5
5
|
import { Fragment as _Fragment } from "react/jsx-runtime";
|
|
6
6
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
7
7
|
import { jsxs as _jsxs } from "react/jsx-runtime";
|
|
8
|
-
var
|
|
9
|
-
// contenteditable 无法把光标放进 contenteditable=false
|
|
8
|
+
var MENTION_ATTR = "data-xadk-inline-mention-id";
|
|
9
|
+
// contenteditable 无法把光标放进 contenteditable=false 的 Mention 里,需用零宽字符承接“Mention 后方”的光标。
|
|
10
10
|
var CARET_TEXT = "\u200B";
|
|
11
11
|
var createTextNode = function createTextNode(text) {
|
|
12
12
|
return document.createTextNode(text);
|
|
@@ -29,38 +29,40 @@ var toRawOffset = function toRawOffset(text, plainOffset) {
|
|
|
29
29
|
};
|
|
30
30
|
var InlineTagInput = /*#__PURE__*/forwardRef(function (_ref, ref) {
|
|
31
31
|
var value = _ref.value,
|
|
32
|
-
|
|
32
|
+
mentions = _ref.mentions,
|
|
33
|
+
defaultInputParts = _ref.defaultInputParts,
|
|
33
34
|
placeholder = _ref.placeholder,
|
|
34
35
|
disabled = _ref.disabled,
|
|
35
36
|
onChange = _ref.onChange,
|
|
36
|
-
|
|
37
|
+
onMentionsChange = _ref.onMentionsChange,
|
|
37
38
|
onKeyDown = _ref.onKeyDown,
|
|
38
39
|
_onKeyUp = _ref.onKeyUp,
|
|
39
|
-
|
|
40
|
+
renderMention = _ref.renderMention;
|
|
40
41
|
var styles = useStyles();
|
|
41
42
|
var editorRef = useRef(null);
|
|
42
|
-
var
|
|
43
|
+
var latestMentionsRef = useRef(mentions);
|
|
43
44
|
var tagRootMapRef = useRef(new WeakMap());
|
|
44
45
|
var composingRef = useRef(false);
|
|
45
46
|
var lastInsertedCaretRef = useRef(null);
|
|
46
47
|
var savedRangeRef = useRef(null);
|
|
48
|
+
var defaultInputPartsAppliedRef = useRef(false);
|
|
47
49
|
var lastEmittedStateRef = useRef({
|
|
48
50
|
value: value,
|
|
49
|
-
|
|
50
|
-
return
|
|
51
|
+
mentionIds: mentions.map(function (mention) {
|
|
52
|
+
return mention.id;
|
|
51
53
|
}).join("|")
|
|
52
54
|
});
|
|
53
55
|
useEffect(function () {
|
|
54
|
-
|
|
55
|
-
}, [
|
|
56
|
-
var
|
|
56
|
+
latestMentionsRef.current = mentions;
|
|
57
|
+
}, [mentions]);
|
|
58
|
+
var getOrderedMentions = useCallback(function () {
|
|
57
59
|
var editor = editorRef.current;
|
|
58
60
|
if (!editor) return [];
|
|
59
|
-
var
|
|
60
|
-
return [
|
|
61
|
+
var mentionMap = new Map(latestMentionsRef.current.map(function (mention) {
|
|
62
|
+
return [mention.id, mention];
|
|
61
63
|
}));
|
|
62
|
-
return Array.from(editor.querySelectorAll("[".concat(
|
|
63
|
-
return
|
|
64
|
+
return Array.from(editor.querySelectorAll("[".concat(MENTION_ATTR, "]"))).map(function (node) {
|
|
65
|
+
return mentionMap.get(node.dataset.xadkInlineMentionId || "");
|
|
64
66
|
}).filter(Boolean);
|
|
65
67
|
}, []);
|
|
66
68
|
|
|
@@ -77,12 +79,12 @@ var InlineTagInput = /*#__PURE__*/forwardRef(function (_ref, ref) {
|
|
|
77
79
|
return normalizeText(text);
|
|
78
80
|
}, []);
|
|
79
81
|
|
|
80
|
-
// 提交时需要保留文本与
|
|
82
|
+
// 提交时需要保留文本与 Mention 的真实顺序;仅靠 value + mentions 无法区分 Mention 在句首、句中还是句尾。
|
|
81
83
|
var getParts = useCallback(function () {
|
|
82
84
|
var editor = editorRef.current;
|
|
83
85
|
if (!editor) return [];
|
|
84
|
-
var
|
|
85
|
-
return [
|
|
86
|
+
var mentionMap = new Map(latestMentionsRef.current.map(function (mention) {
|
|
87
|
+
return [mention.id, mention];
|
|
86
88
|
}));
|
|
87
89
|
var parts = [];
|
|
88
90
|
editor.childNodes.forEach(function (node) {
|
|
@@ -94,12 +96,12 @@ var InlineTagInput = /*#__PURE__*/forwardRef(function (_ref, ref) {
|
|
|
94
96
|
});
|
|
95
97
|
return;
|
|
96
98
|
}
|
|
97
|
-
if (node instanceof HTMLElement && node.hasAttribute(
|
|
98
|
-
var
|
|
99
|
-
var
|
|
100
|
-
if (
|
|
101
|
-
type: "
|
|
102
|
-
|
|
99
|
+
if (node instanceof HTMLElement && node.hasAttribute(MENTION_ATTR)) {
|
|
100
|
+
var mentionId = node.dataset.xadkInlineMentionId || "";
|
|
101
|
+
var _mention = mentionMap.get(mentionId);
|
|
102
|
+
if (_mention) parts.push({
|
|
103
|
+
type: "mention",
|
|
104
|
+
mention: _mention
|
|
103
105
|
});
|
|
104
106
|
}
|
|
105
107
|
});
|
|
@@ -107,29 +109,29 @@ var InlineTagInput = /*#__PURE__*/forwardRef(function (_ref, ref) {
|
|
|
107
109
|
}, []);
|
|
108
110
|
var emitChange = useCallback(function () {
|
|
109
111
|
var nextValue = getPlainText();
|
|
110
|
-
var
|
|
112
|
+
var nextMentions = getOrderedMentions();
|
|
111
113
|
lastEmittedStateRef.current = {
|
|
112
114
|
value: nextValue,
|
|
113
|
-
|
|
114
|
-
return
|
|
115
|
+
mentionIds: nextMentions.map(function (mention) {
|
|
116
|
+
return mention.id;
|
|
115
117
|
}).join("|")
|
|
116
118
|
};
|
|
117
119
|
onChange(nextValue);
|
|
118
|
-
|
|
119
|
-
}, [
|
|
120
|
+
onMentionsChange(nextMentions);
|
|
121
|
+
}, [getOrderedMentions, getPlainText, onChange, onMentionsChange]);
|
|
120
122
|
var removeTextRange = useCallback(function (node, start, end) {
|
|
121
123
|
var text = node.textContent || "";
|
|
122
124
|
node.textContent = "".concat(text.slice(0, start)).concat(text.slice(end));
|
|
123
125
|
if (!node.textContent) node.remove();
|
|
124
126
|
}, []);
|
|
125
|
-
var
|
|
127
|
+
var removeMentionNode = useCallback(function (node) {
|
|
126
128
|
var _tagRootMapRef$curren;
|
|
127
129
|
var previous = node.previousSibling;
|
|
128
130
|
var next = node.nextSibling;
|
|
129
131
|
(_tagRootMapRef$curren = tagRootMapRef.current.get(node)) === null || _tagRootMapRef$curren === void 0 || _tagRootMapRef$curren.unmount();
|
|
130
132
|
node.remove();
|
|
131
133
|
|
|
132
|
-
//
|
|
134
|
+
// Mention 后会补一个不可见光标锚点;删除 Mention 时同步清理,避免留下冗余节点。
|
|
133
135
|
if ((next === null || next === void 0 ? void 0 : next.nodeType) === Node.TEXT_NODE) {
|
|
134
136
|
var _text$match;
|
|
135
137
|
var text = next.textContent || "";
|
|
@@ -148,51 +150,68 @@ var InlineTagInput = /*#__PURE__*/forwardRef(function (_ref, ref) {
|
|
|
148
150
|
}
|
|
149
151
|
}
|
|
150
152
|
}, [removeTextRange]);
|
|
151
|
-
var
|
|
153
|
+
var removeMentionById = useCallback(function (id) {
|
|
152
154
|
var editor = editorRef.current;
|
|
153
|
-
var node = Array.from((editor === null || editor === void 0 ? void 0 : editor.querySelectorAll("[".concat(
|
|
154
|
-
return item.dataset.
|
|
155
|
+
var node = Array.from((editor === null || editor === void 0 ? void 0 : editor.querySelectorAll("[".concat(MENTION_ATTR, "]"))) || []).find(function (item) {
|
|
156
|
+
return item.dataset.xadkInlineMentionId === id;
|
|
155
157
|
});
|
|
156
158
|
if (node) {
|
|
157
|
-
|
|
159
|
+
removeMentionNode(node);
|
|
158
160
|
}
|
|
159
161
|
emitChange();
|
|
160
162
|
editor === null || editor === void 0 || editor.focus();
|
|
161
|
-
}, [emitChange,
|
|
163
|
+
}, [emitChange, removeMentionNode]);
|
|
162
164
|
|
|
163
|
-
//
|
|
164
|
-
var
|
|
165
|
+
// Mention 节点本身不可编辑;删除入口通过 onRemove 回到组件内部统一维护 DOM 与 mentions。
|
|
166
|
+
var buildMentionNode = useCallback(function (mention) {
|
|
165
167
|
var span = document.createElement("span");
|
|
166
168
|
span.setAttribute("contenteditable", "false");
|
|
167
|
-
span.setAttribute(
|
|
168
|
-
span.dataset.
|
|
169
|
+
span.setAttribute(MENTION_ATTR, mention.id);
|
|
170
|
+
span.dataset.xadkInlineMentionId = mention.id;
|
|
169
171
|
span.className = styles.inlineTag;
|
|
170
|
-
if (
|
|
172
|
+
if (renderMention) {
|
|
171
173
|
var root = createRoot(span);
|
|
172
174
|
tagRootMapRef.current.set(span, root);
|
|
173
175
|
root.render( /*#__PURE__*/_jsx(_Fragment, {
|
|
174
|
-
children:
|
|
176
|
+
children: renderMention(mention, {
|
|
175
177
|
onRemove: function onRemove() {
|
|
176
|
-
return
|
|
178
|
+
return removeMentionById(mention.id);
|
|
177
179
|
}
|
|
178
180
|
})
|
|
179
181
|
}));
|
|
180
182
|
} else {
|
|
181
183
|
var label = document.createElement("span");
|
|
182
184
|
label.className = "xadk-inline-tag-label";
|
|
183
|
-
label.textContent =
|
|
185
|
+
label.textContent = mention.displayName || mention.label;
|
|
184
186
|
var close = document.createElement("span");
|
|
185
187
|
close.className = "xadk-inline-tag-close";
|
|
186
188
|
close.innerHTML = "×";
|
|
187
189
|
close.onclick = function (event) {
|
|
188
190
|
event.preventDefault();
|
|
189
191
|
event.stopPropagation();
|
|
190
|
-
|
|
192
|
+
removeMentionById(mention.id);
|
|
191
193
|
};
|
|
192
194
|
span.append(label, close);
|
|
193
195
|
}
|
|
194
196
|
return span;
|
|
195
|
-
}, [
|
|
197
|
+
}, [removeMentionById, renderMention, styles.inlineTag]);
|
|
198
|
+
var renderPartsToEditor = useCallback(function (parts) {
|
|
199
|
+
var editor = editorRef.current;
|
|
200
|
+
if (!editor) return;
|
|
201
|
+
editor.querySelectorAll("[".concat(MENTION_ATTR, "]")).forEach(function (node) {
|
|
202
|
+
var _tagRootMapRef$curren2;
|
|
203
|
+
(_tagRootMapRef$curren2 = tagRootMapRef.current.get(node)) === null || _tagRootMapRef$curren2 === void 0 || _tagRootMapRef$curren2.unmount();
|
|
204
|
+
});
|
|
205
|
+
editor.innerHTML = "";
|
|
206
|
+
parts.forEach(function (part) {
|
|
207
|
+
if (part.type === "text") {
|
|
208
|
+
if (part.text) editor.appendChild(createTextNode(part.text));
|
|
209
|
+
return;
|
|
210
|
+
}
|
|
211
|
+
var mention = part.type === "mention" ? part.mention : part.tag;
|
|
212
|
+
editor.append(buildMentionNode(mention), createTextNode(CARET_TEXT));
|
|
213
|
+
});
|
|
214
|
+
}, [buildMentionNode]);
|
|
196
215
|
var setCursorAtTextEnd = useCallback(function (node) {
|
|
197
216
|
var _node$textContent;
|
|
198
217
|
var range = document.createRange();
|
|
@@ -219,52 +238,52 @@ var InlineTagInput = /*#__PURE__*/forwardRef(function (_ref, ref) {
|
|
|
219
238
|
editor.focus();
|
|
220
239
|
setCursorAtTextEnd(node);
|
|
221
240
|
}, [setCursorAtTextEnd]);
|
|
222
|
-
var
|
|
223
|
-
return node instanceof HTMLElement && node.hasAttribute(
|
|
241
|
+
var isMentionNode = function isMentionNode(node) {
|
|
242
|
+
return node instanceof HTMLElement && node.hasAttribute(MENTION_ATTR);
|
|
224
243
|
};
|
|
225
244
|
var isOnlyCaretText = function isOnlyCaretText(text) {
|
|
226
245
|
return normalizeText(text) === "";
|
|
227
246
|
};
|
|
228
247
|
|
|
229
|
-
// Backspace/Delete
|
|
230
|
-
var
|
|
248
|
+
// Backspace/Delete 需要跨过零宽锚点识别相邻 Mention,不能只看光标所在文本节点。
|
|
249
|
+
var getMentionBeforeRange = function getMentionBeforeRange(range) {
|
|
231
250
|
var container = range.startContainer;
|
|
232
251
|
if (container.nodeType === Node.TEXT_NODE) {
|
|
233
252
|
var text = container.textContent || "";
|
|
234
253
|
var beforeCursor = text.slice(0, range.startOffset);
|
|
235
|
-
if (isOnlyCaretText(beforeCursor) &&
|
|
254
|
+
if (isOnlyCaretText(beforeCursor) && isMentionNode(container.previousSibling)) {
|
|
236
255
|
return container.previousSibling;
|
|
237
256
|
}
|
|
238
257
|
}
|
|
239
258
|
if (container instanceof HTMLElement) {
|
|
240
259
|
var previous = container.childNodes[range.startOffset - 1];
|
|
241
|
-
if (
|
|
242
|
-
if ((previous === null || previous === void 0 ? void 0 : previous.nodeType) === Node.TEXT_NODE && isOnlyCaretText(previous.textContent || "") &&
|
|
260
|
+
if (isMentionNode(previous)) return previous;
|
|
261
|
+
if ((previous === null || previous === void 0 ? void 0 : previous.nodeType) === Node.TEXT_NODE && isOnlyCaretText(previous.textContent || "") && isMentionNode(previous.previousSibling)) {
|
|
243
262
|
return previous.previousSibling;
|
|
244
263
|
}
|
|
245
264
|
}
|
|
246
265
|
return null;
|
|
247
266
|
};
|
|
248
|
-
var
|
|
267
|
+
var getMentionAfterRange = function getMentionAfterRange(range) {
|
|
249
268
|
var container = range.startContainer;
|
|
250
269
|
if (container.nodeType === Node.TEXT_NODE) {
|
|
251
270
|
var text = container.textContent || "";
|
|
252
271
|
var afterCursor = text.slice(range.startOffset);
|
|
253
|
-
if (isOnlyCaretText(afterCursor) &&
|
|
272
|
+
if (isOnlyCaretText(afterCursor) && isMentionNode(container.nextSibling)) {
|
|
254
273
|
return container.nextSibling;
|
|
255
274
|
}
|
|
256
275
|
}
|
|
257
276
|
if (container instanceof HTMLElement) {
|
|
258
277
|
var next = container.childNodes[range.startOffset];
|
|
259
|
-
if (
|
|
260
|
-
if ((next === null || next === void 0 ? void 0 : next.nodeType) === Node.TEXT_NODE && isOnlyCaretText(next.textContent || "") &&
|
|
278
|
+
if (isMentionNode(next)) return next;
|
|
279
|
+
if ((next === null || next === void 0 ? void 0 : next.nodeType) === Node.TEXT_NODE && isOnlyCaretText(next.textContent || "") && isMentionNode(next.nextSibling)) {
|
|
261
280
|
return next.nextSibling;
|
|
262
281
|
}
|
|
263
282
|
}
|
|
264
283
|
return null;
|
|
265
284
|
};
|
|
266
285
|
|
|
267
|
-
// 读取光标在纯文本中的位置,供快捷键搜索词和
|
|
286
|
+
// 读取光标在纯文本中的位置,供快捷键搜索词和 Mention 插入位置复用。
|
|
268
287
|
var getOffsetInEditor = useCallback(function () {
|
|
269
288
|
var editor = editorRef.current;
|
|
270
289
|
var selection = window.getSelection();
|
|
@@ -281,7 +300,7 @@ var InlineTagInput = /*#__PURE__*/forwardRef(function (_ref, ref) {
|
|
|
281
300
|
found = true;
|
|
282
301
|
return;
|
|
283
302
|
}
|
|
284
|
-
if (node instanceof HTMLElement && node.hasAttribute(
|
|
303
|
+
if (node instanceof HTMLElement && node.hasAttribute(MENTION_ATTR)) return;
|
|
285
304
|
if (node.nodeType === Node.TEXT_NODE) {
|
|
286
305
|
offset += getPlainLength(node.textContent || "");
|
|
287
306
|
return;
|
|
@@ -301,8 +320,8 @@ var InlineTagInput = /*#__PURE__*/forwardRef(function (_ref, ref) {
|
|
|
301
320
|
return index;
|
|
302
321
|
};
|
|
303
322
|
|
|
304
|
-
// 删除快捷键触发片段,例如把 “@文档” 替换成一个结构化
|
|
305
|
-
// 注意:纯文本 offset 不包含
|
|
323
|
+
// 删除快捷键触发片段,例如把 “@文档” 替换成一个结构化 Mention,并返回删除位置对应的真实 DOM Range。
|
|
324
|
+
// 注意:纯文本 offset 不包含 Mention,Mention 前后可能都是 offset 0;插入 Mention 必须依赖真实 Range,不能再反推 offset。
|
|
306
325
|
var replaceTextRange = useCallback(function (start, end) {
|
|
307
326
|
var editor = editorRef.current;
|
|
308
327
|
if (!editor) return null;
|
|
@@ -338,7 +357,7 @@ var InlineTagInput = /*#__PURE__*/forwardRef(function (_ref, ref) {
|
|
|
338
357
|
return insertRange;
|
|
339
358
|
}, []);
|
|
340
359
|
|
|
341
|
-
// 浏览器拆分 Range 后可能留下空文本节点;清理后才能保证后续
|
|
360
|
+
// 浏览器拆分 Range 后可能留下空文本节点;清理后才能保证后续 Mention 继续 append 在队尾。
|
|
342
361
|
var cleanupCaretTextNodes = useCallback(function () {
|
|
343
362
|
var editor = editorRef.current;
|
|
344
363
|
if (!editor) return;
|
|
@@ -354,44 +373,44 @@ var InlineTagInput = /*#__PURE__*/forwardRef(function (_ref, ref) {
|
|
|
354
373
|
}
|
|
355
374
|
});
|
|
356
375
|
}, []);
|
|
357
|
-
var
|
|
376
|
+
var insertMention = useCallback(function (mention, replace) {
|
|
358
377
|
var editor = editorRef.current;
|
|
359
378
|
if (!editor) return;
|
|
360
379
|
editor.focus();
|
|
361
|
-
|
|
362
|
-
return item.id !==
|
|
363
|
-
})), [
|
|
380
|
+
latestMentionsRef.current = [].concat(_toConsumableArray(latestMentionsRef.current.filter(function (item) {
|
|
381
|
+
return item.id !== mention.id;
|
|
382
|
+
})), [mention]);
|
|
364
383
|
var insertRange = null;
|
|
365
384
|
if (replace) {
|
|
366
385
|
insertRange = replaceTextRange(replace.start, replace.end);
|
|
367
386
|
cleanupCaretTextNodes();
|
|
368
387
|
}
|
|
369
|
-
var
|
|
388
|
+
var mentionNode = buildMentionNode(mention);
|
|
370
389
|
var caretNode = createTextNode(CARET_TEXT);
|
|
371
390
|
var selection = window.getSelection();
|
|
372
391
|
var savedRange = savedRangeRef.current;
|
|
373
392
|
var range = insertRange || (selection !== null && selection !== void 0 && selection.rangeCount && editor.contains(selection.getRangeAt(0).startContainer) ? selection.getRangeAt(0) : savedRange && editor.contains(savedRange.startContainer) ? savedRange : null);
|
|
374
393
|
if (range && editor.contains(range.startContainer)) {
|
|
375
|
-
// 用 DocumentFragment 一次性插入,避免连续 insertNode 导致
|
|
394
|
+
// 用 DocumentFragment 一次性插入,避免连续 insertNode 导致 mention/caret 顺序被浏览器 Range 状态打乱。
|
|
376
395
|
var fragment = document.createDocumentFragment();
|
|
377
|
-
fragment.append(
|
|
396
|
+
fragment.append(mentionNode, caretNode);
|
|
378
397
|
range.insertNode(fragment);
|
|
379
398
|
} else {
|
|
380
|
-
editor.append(
|
|
399
|
+
editor.append(mentionNode, caretNode);
|
|
381
400
|
}
|
|
382
401
|
cleanupCaretTextNodes();
|
|
383
402
|
lastInsertedCaretRef.current = caretNode;
|
|
384
403
|
setCursorAtTextEnd(caretNode);
|
|
385
404
|
emitChange();
|
|
386
405
|
|
|
387
|
-
// 关闭快捷列表和父组件同步
|
|
388
|
-
// 下一帧再恢复到刚插入
|
|
406
|
+
// 关闭快捷列表和父组件同步 mentions/value 会触发一次 React 更新;
|
|
407
|
+
// 下一帧再恢复到刚插入 Mention 后的零宽锚点,避免光标被 focus 或重渲染带回旧位置。
|
|
389
408
|
window.requestAnimationFrame(function () {
|
|
390
409
|
if (lastInsertedCaretRef.current === caretNode) {
|
|
391
410
|
restoreCursorAfterInsert(caretNode);
|
|
392
411
|
}
|
|
393
412
|
});
|
|
394
|
-
}, [
|
|
413
|
+
}, [buildMentionNode, cleanupCaretTextNodes, emitChange, replaceTextRange, restoreCursorAfterInsert, setCursorAtTextEnd]);
|
|
395
414
|
useEffect(function () {
|
|
396
415
|
document.addEventListener("selectionchange", saveSelectionRange);
|
|
397
416
|
return function () {
|
|
@@ -407,47 +426,56 @@ var InlineTagInput = /*#__PURE__*/forwardRef(function (_ref, ref) {
|
|
|
407
426
|
getText: getPlainText,
|
|
408
427
|
getParts: getParts,
|
|
409
428
|
getCursorOffset: getOffsetInEditor,
|
|
410
|
-
|
|
429
|
+
insertMention: insertMention,
|
|
430
|
+
insertTag: insertMention
|
|
411
431
|
};
|
|
412
|
-
}, [getOffsetInEditor, getParts, getPlainText,
|
|
432
|
+
}, [getOffsetInEditor, getParts, getPlainText, insertMention]);
|
|
413
433
|
useIsomorphicLayoutEffect(function () {
|
|
414
434
|
var editor = editorRef.current;
|
|
415
435
|
if (!editor) return;
|
|
416
|
-
|
|
417
|
-
|
|
436
|
+
|
|
437
|
+
// 默认片段只在空输入首次挂载时灌入,避免外部重新渲染覆盖用户正在编辑的内容。
|
|
438
|
+
if (!defaultInputPartsAppliedRef.current && defaultInputParts !== null && defaultInputParts !== void 0 && defaultInputParts.length && !value && mentions.length === 0) {
|
|
439
|
+
defaultInputPartsAppliedRef.current = true;
|
|
440
|
+
renderPartsToEditor(defaultInputParts);
|
|
441
|
+
emitChange();
|
|
442
|
+
return;
|
|
443
|
+
}
|
|
444
|
+
var incomingMentionIds = mentions.map(function (mention) {
|
|
445
|
+
return mention.id;
|
|
418
446
|
}).join("|");
|
|
419
447
|
var lastEmittedState = lastEmittedStateRef.current;
|
|
420
|
-
var isInternalControlledEcho = value === lastEmittedState.value &&
|
|
448
|
+
var isInternalControlledEcho = value === lastEmittedState.value && incomingMentionIds === lastEmittedState.mentionIds;
|
|
421
449
|
if (isInternalControlledEcho && editor.childNodes.length > 0) return;
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
})
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
});
|
|
450
|
+
renderPartsToEditor([].concat(_toConsumableArray(value ? [{
|
|
451
|
+
type: "text",
|
|
452
|
+
text: value
|
|
453
|
+
}] : []), _toConsumableArray(mentions.map(function (mention) {
|
|
454
|
+
return {
|
|
455
|
+
type: "mention",
|
|
456
|
+
mention: mention
|
|
457
|
+
};
|
|
458
|
+
}))));
|
|
431
459
|
|
|
432
|
-
// 外部主动写入 value/
|
|
460
|
+
// 外部主动写入 value/mentions 后,需要在首帧绘制前同步 DOM;若输入区已有焦点,则把光标放在内容末尾。
|
|
433
461
|
var lastTextNode = Array.from(editor.childNodes).reverse().find(function (node) {
|
|
434
462
|
return node.nodeType === Node.TEXT_NODE;
|
|
435
463
|
});
|
|
436
464
|
if (document.activeElement === editor && lastTextNode) {
|
|
437
465
|
setCursorAtTextEnd(lastTextNode);
|
|
438
466
|
}
|
|
439
|
-
}, [
|
|
467
|
+
}, [defaultInputParts, emitChange, renderPartsToEditor, setCursorAtTextEnd, mentions, value]);
|
|
440
468
|
useIsomorphicLayoutEffect(function () {
|
|
441
469
|
var editor = editorRef.current;
|
|
442
470
|
if (!editor) return;
|
|
443
|
-
if (!value &&
|
|
444
|
-
editor.querySelectorAll("[".concat(
|
|
471
|
+
if (!value && mentions.length === 0 && editor.childNodes.length > 0) {
|
|
472
|
+
editor.querySelectorAll("[".concat(MENTION_ATTR, "]")).forEach(function (node) {
|
|
445
473
|
var _tagRootMapRef$curren3;
|
|
446
474
|
(_tagRootMapRef$curren3 = tagRootMapRef.current.get(node)) === null || _tagRootMapRef$curren3 === void 0 || _tagRootMapRef$curren3.unmount();
|
|
447
475
|
});
|
|
448
476
|
editor.innerHTML = "";
|
|
449
477
|
}
|
|
450
|
-
}, [
|
|
478
|
+
}, [mentions.length, value]);
|
|
451
479
|
var handleInput = function handleInput() {
|
|
452
480
|
if (!composingRef.current) emitChange();
|
|
453
481
|
};
|
|
@@ -457,10 +485,10 @@ var InlineTagInput = /*#__PURE__*/forwardRef(function (_ref, ref) {
|
|
|
457
485
|
if (selection !== null && selection !== void 0 && selection.rangeCount) {
|
|
458
486
|
var range = selection.getRangeAt(0);
|
|
459
487
|
if (range.collapsed) {
|
|
460
|
-
var
|
|
461
|
-
if (
|
|
488
|
+
var targetMention = event.key === "Backspace" ? getMentionBeforeRange(range) : getMentionAfterRange(range);
|
|
489
|
+
if (targetMention) {
|
|
462
490
|
event.preventDefault();
|
|
463
|
-
|
|
491
|
+
removeMentionById(targetMention.dataset.xadkInlineMentionId || "");
|
|
464
492
|
return;
|
|
465
493
|
}
|
|
466
494
|
}
|
|
@@ -469,8 +497,8 @@ var InlineTagInput = /*#__PURE__*/forwardRef(function (_ref, ref) {
|
|
|
469
497
|
onKeyDown === null || onKeyDown === void 0 || onKeyDown(event);
|
|
470
498
|
};
|
|
471
499
|
|
|
472
|
-
// placeholder 只由受控 value/
|
|
473
|
-
var showPlaceholder = !value &&
|
|
500
|
+
// placeholder 只由受控 value/mentions 派生,避免从 contenteditable DOM 读取导致外部插入 Mention 后状态滞后一帧。
|
|
501
|
+
var showPlaceholder = !value && mentions.length === 0;
|
|
474
502
|
return /*#__PURE__*/_jsxs("div", {
|
|
475
503
|
className: styles.inlineInputWrapper,
|
|
476
504
|
children: [showPlaceholder && placeholder && /*#__PURE__*/_jsx("div", {
|