@ai-group/chat-sdk 3.7.1-alpha2 → 3.7.1-alpha4
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/index.js +59 -40
- package/dist/cjs/components/FileGallery/index.js.map +2 -2
- package/dist/cjs/components/FileGallery/styles.d.ts +7 -0
- package/dist/cjs/components/FileGallery/styles.js +78 -0
- package/dist/cjs/components/FileGallery/styles.js.map +2 -2
- package/dist/cjs/components/XAdkChatbot/components/MarkdownRender/index.d.ts +7 -1
- package/dist/cjs/components/XAdkChatbot/components/MarkdownRender/index.js +82 -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 +35 -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 +188 -113
- 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 +104 -64
- package/dist/cjs/components/XAdkSender/index.js.map +2 -2
- package/dist/cjs/components/XAdkSender/styles.d.ts +4 -0
- package/dist/cjs/components/XAdkSender/styles.js +34 -6
- package/dist/cjs/components/XAdkSender/styles.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/types/FileGallery.d.ts +3 -0
- package/dist/cjs/types/FileGallery.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 +74 -23
- 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 +7 -0
- package/dist/cjs/utils/markdownResource.js +73 -0
- package/dist/cjs/utils/markdownResource.js.map +7 -0
- package/dist/esm/components/FileGallery/index.js +22 -16
- package/dist/esm/components/FileGallery/index.js.map +1 -1
- package/dist/esm/components/FileGallery/styles.d.ts +7 -0
- package/dist/esm/components/FileGallery/styles.js +24 -17
- package/dist/esm/components/FileGallery/styles.js.map +1 -1
- package/dist/esm/components/XAdkChatbot/components/MarkdownRender/index.d.ts +7 -1
- package/dist/esm/components/XAdkChatbot/components/MarkdownRender/index.js +57 -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 +20 -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 +185 -117
- 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 +124 -77
- package/dist/esm/components/XAdkSender/index.js.map +1 -1
- package/dist/esm/components/XAdkSender/styles.d.ts +4 -0
- package/dist/esm/components/XAdkSender/styles.js +29 -25
- package/dist/esm/components/XAdkSender/styles.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/types/FileGallery.d.ts +3 -0
- package/dist/esm/types/FileGallery.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 +74 -23
- 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 +7 -0
- package/dist/esm/utils/markdownResource.js +33 -0
- package/dist/esm/utils/markdownResource.js.map +1 -0
- package/dist/umd/chat-sdk.min.js +1 -1
- package/package.json +1 -1
|
@@ -1,25 +1,31 @@
|
|
|
1
1
|
import React from "react";
|
|
2
|
-
import type { InlineTagRenderInfo,
|
|
2
|
+
import type { InlineTagRenderInfo, MentionTag, XAdkSenderInputPart, XAdkSenderSubmitPart } from "../../types";
|
|
3
3
|
export interface InlineTagInputRef {
|
|
4
4
|
focus: () => void;
|
|
5
5
|
getText: () => string;
|
|
6
6
|
getParts: () => XAdkSenderSubmitPart[];
|
|
7
7
|
getCursorOffset: () => number;
|
|
8
|
-
|
|
8
|
+
insertMention: (mention: MentionTag, replace?: {
|
|
9
|
+
start: number;
|
|
10
|
+
end: number;
|
|
11
|
+
}) => void;
|
|
12
|
+
/** @deprecated 请使用 insertMention。 */
|
|
13
|
+
insertTag: (mention: MentionTag, replace?: {
|
|
9
14
|
start: number;
|
|
10
15
|
end: number;
|
|
11
16
|
}) => void;
|
|
12
17
|
}
|
|
13
18
|
export interface InlineTagInputProps {
|
|
14
19
|
value: string;
|
|
15
|
-
|
|
20
|
+
mentions: MentionTag[];
|
|
21
|
+
defaultInputParts?: XAdkSenderInputPart[];
|
|
16
22
|
placeholder?: string;
|
|
17
23
|
disabled?: boolean;
|
|
18
24
|
onChange: (value: string) => void;
|
|
19
|
-
|
|
25
|
+
onMentionsChange: (mentions: MentionTag[]) => void;
|
|
20
26
|
onKeyDown?: React.KeyboardEventHandler<HTMLDivElement>;
|
|
21
27
|
onKeyUp?: React.KeyboardEventHandler<HTMLDivElement>;
|
|
22
|
-
|
|
28
|
+
renderMention?: (mention: MentionTag, info: InlineTagRenderInfo) => React.ReactNode;
|
|
23
29
|
}
|
|
24
30
|
declare const InlineTagInput: React.ForwardRefExoticComponent<InlineTagInputProps & React.RefAttributes<InlineTagInputRef>>;
|
|
25
31
|
export default InlineTagInput;
|
|
@@ -26,9 +26,10 @@ var import_react = require("react");
|
|
|
26
26
|
var import_client = require("react-dom/client");
|
|
27
27
|
var import_styles = require("./styles");
|
|
28
28
|
var import_jsx_runtime = require("react/jsx-runtime");
|
|
29
|
-
var
|
|
29
|
+
var MENTION_ATTR = "data-xadk-inline-mention-id";
|
|
30
30
|
var CARET_TEXT = "";
|
|
31
31
|
var createTextNode = (text) => document.createTextNode(text);
|
|
32
|
+
var useIsomorphicLayoutEffect = typeof window === "undefined" ? import_react.useEffect : import_react.useLayoutEffect;
|
|
32
33
|
var normalizeText = (text) => text.replace(/\u200B/g, "").replace(/\u00a0/g, " ");
|
|
33
34
|
var getPlainLength = (text) => normalizeText(text).length;
|
|
34
35
|
var toRawOffset = (text, plainOffset) => {
|
|
@@ -44,30 +45,41 @@ var toRawOffset = (text, plainOffset) => {
|
|
|
44
45
|
var InlineTagInput = (0, import_react.forwardRef)(
|
|
45
46
|
({
|
|
46
47
|
value,
|
|
47
|
-
|
|
48
|
+
mentions,
|
|
49
|
+
defaultInputParts,
|
|
48
50
|
placeholder,
|
|
49
51
|
disabled,
|
|
50
52
|
onChange,
|
|
51
|
-
|
|
53
|
+
onMentionsChange,
|
|
52
54
|
onKeyDown,
|
|
53
55
|
onKeyUp,
|
|
54
|
-
|
|
56
|
+
renderMention
|
|
55
57
|
}, ref) => {
|
|
56
58
|
const styles = (0, import_styles.useStyles)();
|
|
57
59
|
const editorRef = (0, import_react.useRef)(null);
|
|
58
|
-
const
|
|
60
|
+
const latestMentionsRef = (0, import_react.useRef)(mentions);
|
|
59
61
|
const tagRootMapRef = (0, import_react.useRef)(/* @__PURE__ */ new WeakMap());
|
|
60
62
|
const composingRef = (0, import_react.useRef)(false);
|
|
61
63
|
const lastInsertedCaretRef = (0, import_react.useRef)(null);
|
|
64
|
+
const savedRangeRef = (0, import_react.useRef)(null);
|
|
65
|
+
const defaultInputPartsAppliedRef = (0, import_react.useRef)(false);
|
|
66
|
+
const lastEmittedStateRef = (0, import_react.useRef)({
|
|
67
|
+
value,
|
|
68
|
+
mentionIds: mentions.map((mention) => mention.id).join("|")
|
|
69
|
+
});
|
|
62
70
|
(0, import_react.useEffect)(() => {
|
|
63
|
-
|
|
64
|
-
}, [
|
|
65
|
-
const
|
|
71
|
+
latestMentionsRef.current = mentions;
|
|
72
|
+
}, [mentions]);
|
|
73
|
+
const getOrderedMentions = (0, import_react.useCallback)(() => {
|
|
66
74
|
const editor = editorRef.current;
|
|
67
75
|
if (!editor)
|
|
68
76
|
return [];
|
|
69
|
-
const
|
|
70
|
-
|
|
77
|
+
const mentionMap = new Map(
|
|
78
|
+
latestMentionsRef.current.map((mention) => [mention.id, mention])
|
|
79
|
+
);
|
|
80
|
+
return Array.from(editor.querySelectorAll(`[${MENTION_ATTR}]`)).map(
|
|
81
|
+
(node) => mentionMap.get(node.dataset.xadkInlineMentionId || "")
|
|
82
|
+
).filter(Boolean);
|
|
71
83
|
}, []);
|
|
72
84
|
const getPlainText = (0, import_react.useCallback)(() => {
|
|
73
85
|
const editor = editorRef.current;
|
|
@@ -85,7 +97,9 @@ var InlineTagInput = (0, import_react.forwardRef)(
|
|
|
85
97
|
const editor = editorRef.current;
|
|
86
98
|
if (!editor)
|
|
87
99
|
return [];
|
|
88
|
-
const
|
|
100
|
+
const mentionMap = new Map(
|
|
101
|
+
latestMentionsRef.current.map((mention) => [mention.id, mention])
|
|
102
|
+
);
|
|
89
103
|
const parts = [];
|
|
90
104
|
editor.childNodes.forEach((node) => {
|
|
91
105
|
if (node.nodeType === Node.TEXT_NODE) {
|
|
@@ -94,26 +108,32 @@ var InlineTagInput = (0, import_react.forwardRef)(
|
|
|
94
108
|
parts.push({ type: "text", text });
|
|
95
109
|
return;
|
|
96
110
|
}
|
|
97
|
-
if (node instanceof HTMLElement && node.hasAttribute(
|
|
98
|
-
const
|
|
99
|
-
const
|
|
100
|
-
if (
|
|
101
|
-
parts.push({ type: "
|
|
111
|
+
if (node instanceof HTMLElement && node.hasAttribute(MENTION_ATTR)) {
|
|
112
|
+
const mentionId = node.dataset.xadkInlineMentionId || "";
|
|
113
|
+
const mention = mentionMap.get(mentionId);
|
|
114
|
+
if (mention)
|
|
115
|
+
parts.push({ type: "mention", mention });
|
|
102
116
|
}
|
|
103
117
|
});
|
|
104
118
|
return parts;
|
|
105
119
|
}, []);
|
|
106
120
|
const emitChange = (0, import_react.useCallback)(() => {
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
121
|
+
const nextValue = getPlainText();
|
|
122
|
+
const nextMentions = getOrderedMentions();
|
|
123
|
+
lastEmittedStateRef.current = {
|
|
124
|
+
value: nextValue,
|
|
125
|
+
mentionIds: nextMentions.map((mention) => mention.id).join("|")
|
|
126
|
+
};
|
|
127
|
+
onChange(nextValue);
|
|
128
|
+
onMentionsChange(nextMentions);
|
|
129
|
+
}, [getOrderedMentions, getPlainText, onChange, onMentionsChange]);
|
|
110
130
|
const removeTextRange = (0, import_react.useCallback)((node, start, end) => {
|
|
111
131
|
const text = node.textContent || "";
|
|
112
132
|
node.textContent = `${text.slice(0, start)}${text.slice(end)}`;
|
|
113
133
|
if (!node.textContent)
|
|
114
134
|
node.remove();
|
|
115
135
|
}, []);
|
|
116
|
-
const
|
|
136
|
+
const removeMentionNode = (0, import_react.useCallback)(
|
|
117
137
|
(node) => {
|
|
118
138
|
var _a, _b, _c;
|
|
119
139
|
const previous = node.previousSibling;
|
|
@@ -138,50 +158,76 @@ var InlineTagInput = (0, import_react.forwardRef)(
|
|
|
138
158
|
},
|
|
139
159
|
[removeTextRange]
|
|
140
160
|
);
|
|
141
|
-
const
|
|
161
|
+
const removeMentionById = (0, import_react.useCallback)(
|
|
142
162
|
(id) => {
|
|
143
163
|
const editor = editorRef.current;
|
|
144
|
-
const node = Array.from(
|
|
145
|
-
(
|
|
164
|
+
const node = Array.from(
|
|
165
|
+
(editor == null ? void 0 : editor.querySelectorAll(`[${MENTION_ATTR}]`)) || []
|
|
166
|
+
).find(
|
|
167
|
+
(item) => item.dataset.xadkInlineMentionId === id
|
|
146
168
|
);
|
|
147
169
|
if (node) {
|
|
148
|
-
|
|
170
|
+
removeMentionNode(node);
|
|
149
171
|
}
|
|
150
172
|
emitChange();
|
|
151
173
|
editor == null ? void 0 : editor.focus();
|
|
152
174
|
},
|
|
153
|
-
[emitChange,
|
|
175
|
+
[emitChange, removeMentionNode]
|
|
154
176
|
);
|
|
155
|
-
const
|
|
156
|
-
(
|
|
177
|
+
const buildMentionNode = (0, import_react.useCallback)(
|
|
178
|
+
(mention) => {
|
|
157
179
|
const span = document.createElement("span");
|
|
158
180
|
span.setAttribute("contenteditable", "false");
|
|
159
|
-
span.setAttribute(
|
|
160
|
-
span.dataset.
|
|
181
|
+
span.setAttribute(MENTION_ATTR, mention.id);
|
|
182
|
+
span.dataset.xadkInlineMentionId = mention.id;
|
|
161
183
|
span.className = styles.inlineTag;
|
|
162
|
-
if (
|
|
184
|
+
if (renderMention) {
|
|
163
185
|
const root = (0, import_client.createRoot)(span);
|
|
164
186
|
tagRootMapRef.current.set(span, root);
|
|
165
187
|
root.render(
|
|
166
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_jsx_runtime.Fragment, { children:
|
|
188
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_jsx_runtime.Fragment, { children: renderMention(mention, {
|
|
189
|
+
onRemove: () => removeMentionById(mention.id)
|
|
190
|
+
}) })
|
|
167
191
|
);
|
|
168
192
|
} else {
|
|
169
193
|
const label = document.createElement("span");
|
|
170
194
|
label.className = "xadk-inline-tag-label";
|
|
171
|
-
label.textContent =
|
|
195
|
+
label.textContent = mention.displayName || mention.label;
|
|
172
196
|
const close = document.createElement("span");
|
|
173
197
|
close.className = "xadk-inline-tag-close";
|
|
174
198
|
close.innerHTML = "×";
|
|
175
199
|
close.onclick = (event) => {
|
|
176
200
|
event.preventDefault();
|
|
177
201
|
event.stopPropagation();
|
|
178
|
-
|
|
202
|
+
removeMentionById(mention.id);
|
|
179
203
|
};
|
|
180
204
|
span.append(label, close);
|
|
181
205
|
}
|
|
182
206
|
return span;
|
|
183
207
|
},
|
|
184
|
-
[
|
|
208
|
+
[removeMentionById, renderMention, styles.inlineTag]
|
|
209
|
+
);
|
|
210
|
+
const renderPartsToEditor = (0, import_react.useCallback)(
|
|
211
|
+
(parts) => {
|
|
212
|
+
const editor = editorRef.current;
|
|
213
|
+
if (!editor)
|
|
214
|
+
return;
|
|
215
|
+
editor.querySelectorAll(`[${MENTION_ATTR}]`).forEach((node) => {
|
|
216
|
+
var _a;
|
|
217
|
+
(_a = tagRootMapRef.current.get(node)) == null ? void 0 : _a.unmount();
|
|
218
|
+
});
|
|
219
|
+
editor.innerHTML = "";
|
|
220
|
+
parts.forEach((part) => {
|
|
221
|
+
if (part.type === "text") {
|
|
222
|
+
if (part.text)
|
|
223
|
+
editor.appendChild(createTextNode(part.text));
|
|
224
|
+
return;
|
|
225
|
+
}
|
|
226
|
+
const mention = part.type === "mention" ? part.mention : part.tag;
|
|
227
|
+
editor.append(buildMentionNode(mention), createTextNode(CARET_TEXT));
|
|
228
|
+
});
|
|
229
|
+
},
|
|
230
|
+
[buildMentionNode]
|
|
185
231
|
);
|
|
186
232
|
const setCursorAtTextEnd = (0, import_react.useCallback)((node) => {
|
|
187
233
|
var _a;
|
|
@@ -191,6 +237,18 @@ var InlineTagInput = (0, import_react.forwardRef)(
|
|
|
191
237
|
range.collapse(true);
|
|
192
238
|
selection == null ? void 0 : selection.removeAllRanges();
|
|
193
239
|
selection == null ? void 0 : selection.addRange(range);
|
|
240
|
+
savedRangeRef.current = range.cloneRange();
|
|
241
|
+
}, []);
|
|
242
|
+
const saveSelectionRange = (0, import_react.useCallback)(() => {
|
|
243
|
+
const editor = editorRef.current;
|
|
244
|
+
const selection = window.getSelection();
|
|
245
|
+
if (!editor || !selection || selection.rangeCount === 0)
|
|
246
|
+
return;
|
|
247
|
+
const range = selection.getRangeAt(0);
|
|
248
|
+
if (!editor.contains(range.startContainer) || !editor.contains(range.endContainer)) {
|
|
249
|
+
return;
|
|
250
|
+
}
|
|
251
|
+
savedRangeRef.current = range.cloneRange();
|
|
194
252
|
}, []);
|
|
195
253
|
const restoreCursorAfterInsert = (0, import_react.useCallback)(
|
|
196
254
|
(node) => {
|
|
@@ -202,41 +260,41 @@ var InlineTagInput = (0, import_react.forwardRef)(
|
|
|
202
260
|
},
|
|
203
261
|
[setCursorAtTextEnd]
|
|
204
262
|
);
|
|
205
|
-
const
|
|
263
|
+
const isMentionNode = (node) => node instanceof HTMLElement && node.hasAttribute(MENTION_ATTR);
|
|
206
264
|
const isOnlyCaretText = (text) => normalizeText(text) === "";
|
|
207
|
-
const
|
|
265
|
+
const getMentionBeforeRange = (range) => {
|
|
208
266
|
const container = range.startContainer;
|
|
209
267
|
if (container.nodeType === Node.TEXT_NODE) {
|
|
210
268
|
const text = container.textContent || "";
|
|
211
269
|
const beforeCursor = text.slice(0, range.startOffset);
|
|
212
|
-
if (isOnlyCaretText(beforeCursor) &&
|
|
270
|
+
if (isOnlyCaretText(beforeCursor) && isMentionNode(container.previousSibling)) {
|
|
213
271
|
return container.previousSibling;
|
|
214
272
|
}
|
|
215
273
|
}
|
|
216
274
|
if (container instanceof HTMLElement) {
|
|
217
275
|
const previous = container.childNodes[range.startOffset - 1];
|
|
218
|
-
if (
|
|
276
|
+
if (isMentionNode(previous))
|
|
219
277
|
return previous;
|
|
220
|
-
if ((previous == null ? void 0 : previous.nodeType) === Node.TEXT_NODE && isOnlyCaretText(previous.textContent || "") &&
|
|
278
|
+
if ((previous == null ? void 0 : previous.nodeType) === Node.TEXT_NODE && isOnlyCaretText(previous.textContent || "") && isMentionNode(previous.previousSibling)) {
|
|
221
279
|
return previous.previousSibling;
|
|
222
280
|
}
|
|
223
281
|
}
|
|
224
282
|
return null;
|
|
225
283
|
};
|
|
226
|
-
const
|
|
284
|
+
const getMentionAfterRange = (range) => {
|
|
227
285
|
const container = range.startContainer;
|
|
228
286
|
if (container.nodeType === Node.TEXT_NODE) {
|
|
229
287
|
const text = container.textContent || "";
|
|
230
288
|
const afterCursor = text.slice(range.startOffset);
|
|
231
|
-
if (isOnlyCaretText(afterCursor) &&
|
|
289
|
+
if (isOnlyCaretText(afterCursor) && isMentionNode(container.nextSibling)) {
|
|
232
290
|
return container.nextSibling;
|
|
233
291
|
}
|
|
234
292
|
}
|
|
235
293
|
if (container instanceof HTMLElement) {
|
|
236
294
|
const next = container.childNodes[range.startOffset];
|
|
237
|
-
if (
|
|
295
|
+
if (isMentionNode(next))
|
|
238
296
|
return next;
|
|
239
|
-
if ((next == null ? void 0 : next.nodeType) === Node.TEXT_NODE && isOnlyCaretText(next.textContent || "") &&
|
|
297
|
+
if ((next == null ? void 0 : next.nodeType) === Node.TEXT_NODE && isOnlyCaretText(next.textContent || "") && isMentionNode(next.nextSibling)) {
|
|
240
298
|
return next.nextSibling;
|
|
241
299
|
}
|
|
242
300
|
}
|
|
@@ -262,7 +320,7 @@ var InlineTagInput = (0, import_react.forwardRef)(
|
|
|
262
320
|
found = true;
|
|
263
321
|
return;
|
|
264
322
|
}
|
|
265
|
-
if (node instanceof HTMLElement && node.hasAttribute(
|
|
323
|
+
if (node instanceof HTMLElement && node.hasAttribute(MENTION_ATTR))
|
|
266
324
|
return;
|
|
267
325
|
if (node.nodeType === Node.TEXT_NODE) {
|
|
268
326
|
offset += getPlainLength(node.textContent || "");
|
|
@@ -337,31 +395,32 @@ var InlineTagInput = (0, import_react.forwardRef)(
|
|
|
337
395
|
}
|
|
338
396
|
});
|
|
339
397
|
}, []);
|
|
340
|
-
const
|
|
341
|
-
(
|
|
398
|
+
const insertMention = (0, import_react.useCallback)(
|
|
399
|
+
(mention, replace) => {
|
|
342
400
|
const editor = editorRef.current;
|
|
343
401
|
if (!editor)
|
|
344
402
|
return;
|
|
345
403
|
editor.focus();
|
|
346
|
-
|
|
347
|
-
...
|
|
348
|
-
|
|
404
|
+
latestMentionsRef.current = [
|
|
405
|
+
...latestMentionsRef.current.filter((item) => item.id !== mention.id),
|
|
406
|
+
mention
|
|
349
407
|
];
|
|
350
408
|
let insertRange = null;
|
|
351
409
|
if (replace) {
|
|
352
410
|
insertRange = replaceTextRange(replace.start, replace.end);
|
|
353
411
|
cleanupCaretTextNodes();
|
|
354
412
|
}
|
|
355
|
-
const
|
|
413
|
+
const mentionNode = buildMentionNode(mention);
|
|
356
414
|
const caretNode = createTextNode(CARET_TEXT);
|
|
357
415
|
const selection = window.getSelection();
|
|
358
|
-
const
|
|
416
|
+
const savedRange = savedRangeRef.current;
|
|
417
|
+
const range = insertRange || ((selection == null ? void 0 : selection.rangeCount) && editor.contains(selection.getRangeAt(0).startContainer) ? selection.getRangeAt(0) : savedRange && editor.contains(savedRange.startContainer) ? savedRange : null);
|
|
359
418
|
if (range && editor.contains(range.startContainer)) {
|
|
360
419
|
const fragment = document.createDocumentFragment();
|
|
361
|
-
fragment.append(
|
|
420
|
+
fragment.append(mentionNode, caretNode);
|
|
362
421
|
range.insertNode(fragment);
|
|
363
422
|
} else {
|
|
364
|
-
editor.append(
|
|
423
|
+
editor.append(mentionNode, caretNode);
|
|
365
424
|
}
|
|
366
425
|
cleanupCaretTextNodes();
|
|
367
426
|
lastInsertedCaretRef.current = caretNode;
|
|
@@ -374,7 +433,7 @@ var InlineTagInput = (0, import_react.forwardRef)(
|
|
|
374
433
|
});
|
|
375
434
|
},
|
|
376
435
|
[
|
|
377
|
-
|
|
436
|
+
buildMentionNode,
|
|
378
437
|
cleanupCaretTextNodes,
|
|
379
438
|
emitChange,
|
|
380
439
|
replaceTextRange,
|
|
@@ -382,6 +441,12 @@ var InlineTagInput = (0, import_react.forwardRef)(
|
|
|
382
441
|
setCursorAtTextEnd
|
|
383
442
|
]
|
|
384
443
|
);
|
|
444
|
+
(0, import_react.useEffect)(() => {
|
|
445
|
+
document.addEventListener("selectionchange", saveSelectionRange);
|
|
446
|
+
return () => {
|
|
447
|
+
document.removeEventListener("selectionchange", saveSelectionRange);
|
|
448
|
+
};
|
|
449
|
+
}, [saveSelectionRange]);
|
|
385
450
|
(0, import_react.useImperativeHandle)(ref, () => ({
|
|
386
451
|
focus: () => {
|
|
387
452
|
var _a;
|
|
@@ -390,49 +455,52 @@ var InlineTagInput = (0, import_react.forwardRef)(
|
|
|
390
455
|
getText: getPlainText,
|
|
391
456
|
getParts,
|
|
392
457
|
getCursorOffset: getOffsetInEditor,
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
if (!editor || editor.childNodes.length > 0)
|
|
398
|
-
return;
|
|
399
|
-
if (value)
|
|
400
|
-
editor.appendChild(createTextNode(value));
|
|
401
|
-
tags.forEach((tag) => editor.append(buildTagNode(tag), createTextNode(CARET_TEXT)));
|
|
402
|
-
}, []);
|
|
403
|
-
(0, import_react.useEffect)(() => {
|
|
458
|
+
insertMention,
|
|
459
|
+
insertTag: insertMention
|
|
460
|
+
}), [getOffsetInEditor, getParts, getPlainText, insertMention]);
|
|
461
|
+
useIsomorphicLayoutEffect(() => {
|
|
404
462
|
const editor = editorRef.current;
|
|
405
463
|
if (!editor)
|
|
406
464
|
return;
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
465
|
+
if (!defaultInputPartsAppliedRef.current && (defaultInputParts == null ? void 0 : defaultInputParts.length) && !value && mentions.length === 0) {
|
|
466
|
+
defaultInputPartsAppliedRef.current = true;
|
|
467
|
+
renderPartsToEditor(defaultInputParts);
|
|
468
|
+
emitChange();
|
|
469
|
+
return;
|
|
470
|
+
}
|
|
471
|
+
const incomingMentionIds = mentions.map((mention) => mention.id).join("|");
|
|
472
|
+
const lastEmittedState = lastEmittedStateRef.current;
|
|
473
|
+
const isInternalControlledEcho = value === lastEmittedState.value && incomingMentionIds === lastEmittedState.mentionIds;
|
|
474
|
+
if (isInternalControlledEcho && editor.childNodes.length > 0)
|
|
475
|
+
return;
|
|
476
|
+
renderPartsToEditor([
|
|
477
|
+
...value ? [{ type: "text", text: value }] : [],
|
|
478
|
+
...mentions.map((mention) => ({ type: "mention", mention }))
|
|
479
|
+
]);
|
|
480
|
+
const lastTextNode = Array.from(editor.childNodes).reverse().find((node) => node.nodeType === Node.TEXT_NODE);
|
|
481
|
+
if (document.activeElement === editor && lastTextNode) {
|
|
482
|
+
setCursorAtTextEnd(lastTextNode);
|
|
483
|
+
}
|
|
484
|
+
}, [
|
|
485
|
+
defaultInputParts,
|
|
486
|
+
emitChange,
|
|
487
|
+
renderPartsToEditor,
|
|
488
|
+
setCursorAtTextEnd,
|
|
489
|
+
mentions,
|
|
490
|
+
value
|
|
491
|
+
]);
|
|
492
|
+
useIsomorphicLayoutEffect(() => {
|
|
425
493
|
const editor = editorRef.current;
|
|
426
494
|
if (!editor)
|
|
427
495
|
return;
|
|
428
|
-
if (!value &&
|
|
429
|
-
editor.querySelectorAll(`[${
|
|
496
|
+
if (!value && mentions.length === 0 && editor.childNodes.length > 0) {
|
|
497
|
+
editor.querySelectorAll(`[${MENTION_ATTR}]`).forEach((node) => {
|
|
430
498
|
var _a;
|
|
431
499
|
(_a = tagRootMapRef.current.get(node)) == null ? void 0 : _a.unmount();
|
|
432
500
|
});
|
|
433
501
|
editor.innerHTML = "";
|
|
434
502
|
}
|
|
435
|
-
}, [
|
|
503
|
+
}, [mentions.length, value]);
|
|
436
504
|
const handleInput = () => {
|
|
437
505
|
if (!composingRef.current)
|
|
438
506
|
emitChange();
|
|
@@ -443,10 +511,10 @@ var InlineTagInput = (0, import_react.forwardRef)(
|
|
|
443
511
|
if (selection == null ? void 0 : selection.rangeCount) {
|
|
444
512
|
const range = selection.getRangeAt(0);
|
|
445
513
|
if (range.collapsed) {
|
|
446
|
-
const
|
|
447
|
-
if (
|
|
514
|
+
const targetMention = event.key === "Backspace" ? getMentionBeforeRange(range) : getMentionAfterRange(range);
|
|
515
|
+
if (targetMention) {
|
|
448
516
|
event.preventDefault();
|
|
449
|
-
|
|
517
|
+
removeMentionById(targetMention.dataset.xadkInlineMentionId || "");
|
|
450
518
|
return;
|
|
451
519
|
}
|
|
452
520
|
}
|
|
@@ -454,30 +522,37 @@ var InlineTagInput = (0, import_react.forwardRef)(
|
|
|
454
522
|
}
|
|
455
523
|
onKeyDown == null ? void 0 : onKeyDown(event);
|
|
456
524
|
};
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
{
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
525
|
+
const showPlaceholder = !value && mentions.length === 0;
|
|
526
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: styles.inlineInputWrapper, children: [
|
|
527
|
+
showPlaceholder && placeholder && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: styles.inlinePlaceholder, children: placeholder }),
|
|
528
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
529
|
+
"div",
|
|
530
|
+
{
|
|
531
|
+
ref: editorRef,
|
|
532
|
+
className: styles.inlineInput,
|
|
533
|
+
contentEditable: !disabled,
|
|
534
|
+
suppressContentEditableWarning: true,
|
|
535
|
+
role: "textbox",
|
|
536
|
+
"aria-multiline": "true",
|
|
537
|
+
onInput: handleInput,
|
|
538
|
+
onKeyDown: handleKeyDown,
|
|
539
|
+
onKeyUp: (event) => {
|
|
540
|
+
saveSelectionRange();
|
|
541
|
+
onKeyUp == null ? void 0 : onKeyUp(event);
|
|
542
|
+
},
|
|
543
|
+
onMouseUp: saveSelectionRange,
|
|
544
|
+
onFocus: saveSelectionRange,
|
|
545
|
+
onCompositionStart: () => {
|
|
546
|
+
composingRef.current = true;
|
|
547
|
+
},
|
|
548
|
+
onCompositionEnd: () => {
|
|
549
|
+
composingRef.current = false;
|
|
550
|
+
emitChange();
|
|
551
|
+
},
|
|
552
|
+
"data-cursor-offset": getOffsetInEditor()
|
|
553
|
+
}
|
|
554
|
+
)
|
|
555
|
+
] });
|
|
481
556
|
}
|
|
482
557
|
);
|
|
483
558
|
InlineTagInput.displayName = "InlineTagInput";
|