@douyinfe/semi-foundation 2.88.0-alpha.4 → 2.88.0-alpha.7
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/aiChatInput/foundation.ts +33 -7
- package/aiChatInput/interface.ts +4 -4
- package/aiChatInput/utils.ts +35 -7
- package/lib/cjs/aiChatInput/foundation.d.ts +1 -0
- package/lib/cjs/aiChatInput/foundation.js +36 -6
- package/lib/cjs/aiChatInput/interface.d.ts +4 -4
- package/lib/cjs/aiChatInput/utils.d.ts +12 -3
- package/lib/cjs/aiChatInput/utils.js +38 -8
- package/lib/es/aiChatInput/foundation.d.ts +1 -0
- package/lib/es/aiChatInput/foundation.js +37 -7
- package/lib/es/aiChatInput/interface.d.ts +4 -4
- package/lib/es/aiChatInput/utils.d.ts +12 -3
- package/lib/es/aiChatInput/utils.js +37 -8
- package/package.json +4 -4
|
@@ -2,7 +2,7 @@ import BaseFoundation, { DefaultAdapter } from '../base/foundation';
|
|
|
2
2
|
import { Attachment, BaseSkill, Suggestion, Reference, Content, LeftMenuChangeProps, MessageContent } from './interface';
|
|
3
3
|
import { isNumber, isString } from 'lodash';
|
|
4
4
|
import { cssClasses } from './constants';
|
|
5
|
-
import { transformJSONResult } from './utils';
|
|
5
|
+
import { findSkillSlotInString, transformJSONResult } from './utils';
|
|
6
6
|
|
|
7
7
|
export interface AIChatInputAdapter<P = Record<string, any>, S = Record<string, any>> extends DefaultAdapter<P, S> {
|
|
8
8
|
reposPopover: () => void;
|
|
@@ -16,6 +16,7 @@ export interface AIChatInputAdapter<P = Record<string, any>, S = Record<string,
|
|
|
16
16
|
manualUpload: (files: File[]) => void;
|
|
17
17
|
notifyMessageSend: (props: MessageContent) => void;
|
|
18
18
|
notifyStopGenerate: () => void;
|
|
19
|
+
notifySkillChange: (skill: BaseSkill) => void;
|
|
19
20
|
clearContent: () => void;
|
|
20
21
|
clearAttachments: () => void;
|
|
21
22
|
getRichTextDiv: () => HTMLDivElement | null;
|
|
@@ -51,6 +52,7 @@ export default class AIChatInputFoundation extends BaseFoundation<AIChatInputAda
|
|
|
51
52
|
skill: skill,
|
|
52
53
|
skillVisible: false
|
|
53
54
|
});
|
|
55
|
+
this._adapter.notifySkillChange(skill);
|
|
54
56
|
this._adapter.setContent(`<skill-slot data-value="${skill.label}"></skill-slot>`);
|
|
55
57
|
this._adapter.focusEditor();
|
|
56
58
|
}
|
|
@@ -197,18 +199,27 @@ export default class AIChatInputFoundation extends BaseFoundation<AIChatInputAda
|
|
|
197
199
|
|
|
198
200
|
handleContentChange = (content: string) => {
|
|
199
201
|
const { transformer } = this.getProps();
|
|
200
|
-
const { skill } = this.getStates();
|
|
202
|
+
const { skill = {} } = this.getStates();
|
|
201
203
|
const editor = this._adapter.getEditor();
|
|
202
|
-
const jsonResult = editor.getJSON();
|
|
203
|
-
const finalResult = transformJSONResult(jsonResult, transformer);
|
|
204
|
-
this._adapter.notifyContentChange(finalResult);
|
|
205
204
|
const html = editor.getHTML();
|
|
206
|
-
if (
|
|
205
|
+
if (Object.keys(skill).length && !html.includes('</skill-slot>')) {
|
|
207
206
|
this.setState({
|
|
208
|
-
skill:
|
|
207
|
+
skill: undefined,
|
|
209
208
|
templateVisible: false
|
|
210
209
|
});
|
|
210
|
+
this._adapter.notifySkillChange(undefined);
|
|
211
|
+
this._adapter.notifyContentChange([]);
|
|
212
|
+
return;
|
|
213
|
+
} else if ((Object.keys(skill).length === 0) && html.includes('</skill-slot>')) {
|
|
214
|
+
const newSkill = findSkillSlotInString(html);
|
|
215
|
+
if (newSkill?.value !== skill?.value) {
|
|
216
|
+
this.setState({ skill: newSkill });
|
|
217
|
+
this._adapter.notifySkillChange(newSkill);
|
|
218
|
+
}
|
|
211
219
|
}
|
|
220
|
+
const jsonResult = editor.getJSON();
|
|
221
|
+
const finalResult = transformJSONResult(jsonResult, transformer);
|
|
222
|
+
this._adapter.notifyContentChange(finalResult);
|
|
212
223
|
this.setState({
|
|
213
224
|
content: jsonResult,
|
|
214
225
|
});
|
|
@@ -338,6 +349,21 @@ export default class AIChatInputFoundation extends BaseFoundation<AIChatInputAda
|
|
|
338
349
|
this.handleSend();
|
|
339
350
|
return true;
|
|
340
351
|
}
|
|
352
|
+
if (event.key === 'Enter' && event.shiftKey) {
|
|
353
|
+
/**
|
|
354
|
+
* Tiptap 默认情况下 Enter + Shift 时候是使用 <br /> 实现换行,需要通过新建 p 标签的方式换行保证
|
|
355
|
+
* 自定义的一些逻辑生效(比如零宽字符的插入),因此拦截默认操作,使用新建 p 标签方式
|
|
356
|
+
*/
|
|
357
|
+
event.preventDefault();
|
|
358
|
+
const editor = this._adapter.getEditor();
|
|
359
|
+
if (editor && editor.chain && editor.chain().splitBlock) {
|
|
360
|
+
editor.chain().focus().splitBlock().run();
|
|
361
|
+
} else if (editor && editor.view) {
|
|
362
|
+
const { state, view } = editor;
|
|
363
|
+
view.dispatch(state.tr.split(state.selection.from));
|
|
364
|
+
}
|
|
365
|
+
return true;
|
|
366
|
+
}
|
|
341
367
|
if (event.key !== 'Backspace') return false;
|
|
342
368
|
return false;
|
|
343
369
|
}
|
package/aiChatInput/interface.ts
CHANGED
package/aiChatInput/utils.ts
CHANGED
|
@@ -53,11 +53,10 @@ export function transformSelectSlot(obj: any) {
|
|
|
53
53
|
|
|
54
54
|
export function transformSkillSlot(obj: any) {
|
|
55
55
|
const { type, attrs } = obj;
|
|
56
|
-
const { value
|
|
56
|
+
const { value } = attrs;
|
|
57
57
|
return {
|
|
58
58
|
type,
|
|
59
|
-
value
|
|
60
|
-
...(JSON.parse(info) ?? {}),
|
|
59
|
+
value
|
|
61
60
|
};
|
|
62
61
|
}
|
|
63
62
|
|
|
@@ -71,14 +70,18 @@ export function transformInputSlot(obj: any) {
|
|
|
71
70
|
}
|
|
72
71
|
|
|
73
72
|
export function transformText(obj: any) {
|
|
74
|
-
|
|
73
|
+
const { text } = obj;
|
|
74
|
+
return {
|
|
75
|
+
type: 'text',
|
|
76
|
+
text: text !== strings.ZERO_WIDTH_CHAR ? text : ''
|
|
77
|
+
};
|
|
75
78
|
}
|
|
76
79
|
|
|
77
|
-
export const transformMap = new Map([
|
|
80
|
+
export const transformMap = new Map<string, any>([
|
|
78
81
|
['text', transformText],
|
|
79
82
|
['selectSlot', transformSelectSlot],
|
|
80
83
|
['inputSlot', transformInputSlot],
|
|
81
|
-
['
|
|
84
|
+
['skillSlot', transformSkillSlot],
|
|
82
85
|
]);
|
|
83
86
|
|
|
84
87
|
export function transformJSONResult(input: any, customTransformObj: Map<string, (obj: any) => any> = new Map()) {
|
|
@@ -116,7 +119,7 @@ export function transformJSONResult(input: any, customTransformObj: Map<string,
|
|
|
116
119
|
const lastItem = output[output.length - 1];
|
|
117
120
|
if (lastItem && lastItem.type === 'text') {
|
|
118
121
|
lastItem.text += result.text;
|
|
119
|
-
} else {
|
|
122
|
+
} else if (result.text.length) {
|
|
120
123
|
output.push(result);
|
|
121
124
|
}
|
|
122
125
|
} else {
|
|
@@ -137,4 +140,29 @@ export function getCustomSlotAttribute() {
|
|
|
137
140
|
'data-custom-slot': attributes.isCustomSlot ? 'true' : undefined,
|
|
138
141
|
}),
|
|
139
142
|
};
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
export function findSkillSlotInString(content: string) {
|
|
146
|
+
const reg = /<skill-slot\s+([^>]*)><\/skill-slot>/i;
|
|
147
|
+
const attrReg = /([\w-]+)=["']?([^"'\s>]+)["']?/g;
|
|
148
|
+
const match = reg.exec(content);
|
|
149
|
+
if (match) {
|
|
150
|
+
const attrsStr = match[1];
|
|
151
|
+
let attrMatch;
|
|
152
|
+
let attrs = {};
|
|
153
|
+
while ((attrMatch = attrReg.exec(attrsStr)) !== null) {
|
|
154
|
+
attrs[attrMatch[1]] = attrMatch[2];
|
|
155
|
+
}
|
|
156
|
+
if (attrs['data-value']) {
|
|
157
|
+
const obj = {
|
|
158
|
+
label: attrs['data-label'],
|
|
159
|
+
value: attrs['data-value'],
|
|
160
|
+
hasTemplate: attrs['data-template'] ? attrs['data-template'] === 'true' : undefined
|
|
161
|
+
};
|
|
162
|
+
return Object.fromEntries(
|
|
163
|
+
Object.entries(obj).filter(([key, value]) => value !== undefined)
|
|
164
|
+
);
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
return undefined;
|
|
140
168
|
}
|
|
@@ -12,6 +12,7 @@ export interface AIChatInputAdapter<P = Record<string, any>, S = Record<string,
|
|
|
12
12
|
manualUpload: (files: File[]) => void;
|
|
13
13
|
notifyMessageSend: (props: MessageContent) => void;
|
|
14
14
|
notifyStopGenerate: () => void;
|
|
15
|
+
notifySkillChange: (skill: BaseSkill) => void;
|
|
15
16
|
clearContent: () => void;
|
|
16
17
|
clearAttachments: () => void;
|
|
17
18
|
getRichTextDiv: () => HTMLDivElement | null;
|
|
@@ -24,6 +24,7 @@ class AIChatInputFoundation extends _foundation.default {
|
|
|
24
24
|
skill: skill,
|
|
25
25
|
skillVisible: false
|
|
26
26
|
});
|
|
27
|
+
this._adapter.notifySkillChange(skill);
|
|
27
28
|
this._adapter.setContent(`<skill-slot data-value="${skill.label}"></skill-slot>`);
|
|
28
29
|
this._adapter.focusEditor();
|
|
29
30
|
};
|
|
@@ -167,19 +168,30 @@ class AIChatInputFoundation extends _foundation.default {
|
|
|
167
168
|
transformer
|
|
168
169
|
} = this.getProps();
|
|
169
170
|
const {
|
|
170
|
-
skill
|
|
171
|
+
skill = {}
|
|
171
172
|
} = this.getStates();
|
|
172
173
|
const editor = this._adapter.getEditor();
|
|
173
|
-
const jsonResult = editor.getJSON();
|
|
174
|
-
const finalResult = (0, _utils.transformJSONResult)(jsonResult, transformer);
|
|
175
|
-
this._adapter.notifyContentChange(finalResult);
|
|
176
174
|
const html = editor.getHTML();
|
|
177
|
-
if (
|
|
175
|
+
if (Object.keys(skill).length && !html.includes('</skill-slot>')) {
|
|
178
176
|
this.setState({
|
|
179
|
-
skill:
|
|
177
|
+
skill: undefined,
|
|
180
178
|
templateVisible: false
|
|
181
179
|
});
|
|
180
|
+
this._adapter.notifySkillChange(undefined);
|
|
181
|
+
this._adapter.notifyContentChange([]);
|
|
182
|
+
return;
|
|
183
|
+
} else if (Object.keys(skill).length === 0 && html.includes('</skill-slot>')) {
|
|
184
|
+
const newSkill = (0, _utils.findSkillSlotInString)(html);
|
|
185
|
+
if ((newSkill === null || newSkill === void 0 ? void 0 : newSkill.value) !== (skill === null || skill === void 0 ? void 0 : skill.value)) {
|
|
186
|
+
this.setState({
|
|
187
|
+
skill: newSkill
|
|
188
|
+
});
|
|
189
|
+
this._adapter.notifySkillChange(newSkill);
|
|
190
|
+
}
|
|
182
191
|
}
|
|
192
|
+
const jsonResult = editor.getJSON();
|
|
193
|
+
const finalResult = (0, _utils.transformJSONResult)(jsonResult, transformer);
|
|
194
|
+
this._adapter.notifyContentChange(finalResult);
|
|
183
195
|
this.setState({
|
|
184
196
|
content: jsonResult
|
|
185
197
|
});
|
|
@@ -323,6 +335,24 @@ class AIChatInputFoundation extends _foundation.default {
|
|
|
323
335
|
this.handleSend();
|
|
324
336
|
return true;
|
|
325
337
|
}
|
|
338
|
+
if (event.key === 'Enter' && event.shiftKey) {
|
|
339
|
+
/**
|
|
340
|
+
* Tiptap 默认情况下 Enter + Shift 时候是使用 <br /> 实现换行,需要通过新建 p 标签的方式换行保证
|
|
341
|
+
* 自定义的一些逻辑生效(比如零宽字符的插入),因此拦截默认操作,使用新建 p 标签方式
|
|
342
|
+
*/
|
|
343
|
+
event.preventDefault();
|
|
344
|
+
const editor = this._adapter.getEditor();
|
|
345
|
+
if (editor && editor.chain && editor.chain().splitBlock) {
|
|
346
|
+
editor.chain().focus().splitBlock().run();
|
|
347
|
+
} else if (editor && editor.view) {
|
|
348
|
+
const {
|
|
349
|
+
state,
|
|
350
|
+
view
|
|
351
|
+
} = editor;
|
|
352
|
+
view.dispatch(state.tr.split(state.selection.from));
|
|
353
|
+
}
|
|
354
|
+
return true;
|
|
355
|
+
}
|
|
326
356
|
if (event.key !== 'Backspace') return false;
|
|
327
357
|
return false;
|
|
328
358
|
};
|
|
@@ -4,10 +4,10 @@ export interface RichTextJSON {
|
|
|
4
4
|
[key: string]: any;
|
|
5
5
|
}
|
|
6
6
|
export interface BaseSkill {
|
|
7
|
-
icon
|
|
8
|
-
value
|
|
9
|
-
label
|
|
10
|
-
hasTemplate
|
|
7
|
+
icon?: any;
|
|
8
|
+
value?: string;
|
|
9
|
+
label?: string;
|
|
10
|
+
hasTemplate?: boolean;
|
|
11
11
|
[key: string]: any;
|
|
12
12
|
}
|
|
13
13
|
export type Suggestion = string[] | {
|
|
@@ -6,13 +6,19 @@ export declare function transformSelectSlot(obj: any): {
|
|
|
6
6
|
type: string;
|
|
7
7
|
text: any;
|
|
8
8
|
};
|
|
9
|
-
export declare function transformSkillSlot(obj: any):
|
|
9
|
+
export declare function transformSkillSlot(obj: any): {
|
|
10
|
+
type: any;
|
|
11
|
+
value: any;
|
|
12
|
+
};
|
|
10
13
|
export declare function transformInputSlot(obj: any): {
|
|
11
14
|
type: string;
|
|
12
15
|
text: any;
|
|
13
16
|
};
|
|
14
|
-
export declare function transformText(obj: any):
|
|
15
|
-
|
|
17
|
+
export declare function transformText(obj: any): {
|
|
18
|
+
type: string;
|
|
19
|
+
text: any;
|
|
20
|
+
};
|
|
21
|
+
export declare const transformMap: Map<string, any>;
|
|
16
22
|
export declare function transformJSONResult(input: any, customTransformObj?: Map<string, (obj: any) => any>): any[];
|
|
17
23
|
export declare function getCustomSlotAttribute(): {
|
|
18
24
|
default: boolean;
|
|
@@ -21,3 +27,6 @@ export declare function getCustomSlotAttribute(): {
|
|
|
21
27
|
'data-custom-slot': string;
|
|
22
28
|
};
|
|
23
29
|
};
|
|
30
|
+
export declare function findSkillSlotInString(content: string): {
|
|
31
|
+
[k: string]: any;
|
|
32
|
+
};
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
Object.defineProperty(exports, "__esModule", {
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
|
+
exports.findSkillSlotInString = findSkillSlotInString;
|
|
6
7
|
exports.getAttachmentType = getAttachmentType;
|
|
7
8
|
exports.getContentType = getContentType;
|
|
8
9
|
exports.getCustomSlotAttribute = getCustomSlotAttribute;
|
|
@@ -69,19 +70,17 @@ function transformSelectSlot(obj) {
|
|
|
69
70
|
};
|
|
70
71
|
}
|
|
71
72
|
function transformSkillSlot(obj) {
|
|
72
|
-
var _a;
|
|
73
73
|
const {
|
|
74
74
|
type,
|
|
75
75
|
attrs
|
|
76
76
|
} = obj;
|
|
77
77
|
const {
|
|
78
|
-
value
|
|
79
|
-
info
|
|
78
|
+
value
|
|
80
79
|
} = attrs;
|
|
81
|
-
return
|
|
80
|
+
return {
|
|
82
81
|
type,
|
|
83
82
|
value
|
|
84
|
-
}
|
|
83
|
+
};
|
|
85
84
|
}
|
|
86
85
|
function transformInputSlot(obj) {
|
|
87
86
|
var _a, _b;
|
|
@@ -96,9 +95,15 @@ function transformInputSlot(obj) {
|
|
|
96
95
|
};
|
|
97
96
|
}
|
|
98
97
|
function transformText(obj) {
|
|
99
|
-
|
|
98
|
+
const {
|
|
99
|
+
text
|
|
100
|
+
} = obj;
|
|
101
|
+
return {
|
|
102
|
+
type: 'text',
|
|
103
|
+
text: text !== _constants.strings.ZERO_WIDTH_CHAR ? text : ''
|
|
104
|
+
};
|
|
100
105
|
}
|
|
101
|
-
const transformMap = exports.transformMap = new Map([['text', transformText], ['selectSlot', transformSelectSlot], ['inputSlot', transformInputSlot], ['
|
|
106
|
+
const transformMap = exports.transformMap = new Map([['text', transformText], ['selectSlot', transformSelectSlot], ['inputSlot', transformInputSlot], ['skillSlot', transformSkillSlot]]);
|
|
102
107
|
function transformJSONResult(input) {
|
|
103
108
|
let customTransformObj = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : new Map();
|
|
104
109
|
const output = [];
|
|
@@ -141,7 +146,7 @@ function transformJSONResult(input) {
|
|
|
141
146
|
const lastItem = output[output.length - 1];
|
|
142
147
|
if (lastItem && lastItem.type === 'text') {
|
|
143
148
|
lastItem.text += result.text;
|
|
144
|
-
} else {
|
|
149
|
+
} else if (result.text.length) {
|
|
145
150
|
output.push(result);
|
|
146
151
|
}
|
|
147
152
|
} else {
|
|
@@ -160,4 +165,29 @@ function getCustomSlotAttribute() {
|
|
|
160
165
|
'data-custom-slot': attributes.isCustomSlot ? 'true' : undefined
|
|
161
166
|
})
|
|
162
167
|
};
|
|
168
|
+
}
|
|
169
|
+
function findSkillSlotInString(content) {
|
|
170
|
+
const reg = /<skill-slot\s+([^>]*)><\/skill-slot>/i;
|
|
171
|
+
const attrReg = /([\w-]+)=["']?([^"'\s>]+)["']?/g;
|
|
172
|
+
const match = reg.exec(content);
|
|
173
|
+
if (match) {
|
|
174
|
+
const attrsStr = match[1];
|
|
175
|
+
let attrMatch;
|
|
176
|
+
let attrs = {};
|
|
177
|
+
while ((attrMatch = attrReg.exec(attrsStr)) !== null) {
|
|
178
|
+
attrs[attrMatch[1]] = attrMatch[2];
|
|
179
|
+
}
|
|
180
|
+
if (attrs['data-value']) {
|
|
181
|
+
const obj = {
|
|
182
|
+
label: attrs['data-label'],
|
|
183
|
+
value: attrs['data-value'],
|
|
184
|
+
hasTemplate: attrs['data-template'] ? attrs['data-template'] === 'true' : undefined
|
|
185
|
+
};
|
|
186
|
+
return Object.fromEntries(Object.entries(obj).filter(_ref => {
|
|
187
|
+
let [key, value] = _ref;
|
|
188
|
+
return value !== undefined;
|
|
189
|
+
}));
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
return undefined;
|
|
163
193
|
}
|
|
@@ -12,6 +12,7 @@ export interface AIChatInputAdapter<P = Record<string, any>, S = Record<string,
|
|
|
12
12
|
manualUpload: (files: File[]) => void;
|
|
13
13
|
notifyMessageSend: (props: MessageContent) => void;
|
|
14
14
|
notifyStopGenerate: () => void;
|
|
15
|
+
notifySkillChange: (skill: BaseSkill) => void;
|
|
15
16
|
clearContent: () => void;
|
|
16
17
|
clearAttachments: () => void;
|
|
17
18
|
getRichTextDiv: () => HTMLDivElement | null;
|
|
@@ -2,7 +2,7 @@ import _isString from "lodash/isString";
|
|
|
2
2
|
import _isNumber from "lodash/isNumber";
|
|
3
3
|
import BaseFoundation from '../base/foundation';
|
|
4
4
|
import { cssClasses } from './constants';
|
|
5
|
-
import { transformJSONResult } from './utils';
|
|
5
|
+
import { findSkillSlotInString, transformJSONResult } from './utils';
|
|
6
6
|
const prefixCls = cssClasses.PREFIX;
|
|
7
7
|
export default class AIChatInputFoundation extends BaseFoundation {
|
|
8
8
|
constructor(adapter) {
|
|
@@ -17,6 +17,7 @@ export default class AIChatInputFoundation extends BaseFoundation {
|
|
|
17
17
|
skill: skill,
|
|
18
18
|
skillVisible: false
|
|
19
19
|
});
|
|
20
|
+
this._adapter.notifySkillChange(skill);
|
|
20
21
|
this._adapter.setContent(`<skill-slot data-value="${skill.label}"></skill-slot>`);
|
|
21
22
|
this._adapter.focusEditor();
|
|
22
23
|
};
|
|
@@ -160,19 +161,30 @@ export default class AIChatInputFoundation extends BaseFoundation {
|
|
|
160
161
|
transformer
|
|
161
162
|
} = this.getProps();
|
|
162
163
|
const {
|
|
163
|
-
skill
|
|
164
|
+
skill = {}
|
|
164
165
|
} = this.getStates();
|
|
165
166
|
const editor = this._adapter.getEditor();
|
|
166
|
-
const jsonResult = editor.getJSON();
|
|
167
|
-
const finalResult = transformJSONResult(jsonResult, transformer);
|
|
168
|
-
this._adapter.notifyContentChange(finalResult);
|
|
169
167
|
const html = editor.getHTML();
|
|
170
|
-
if (
|
|
168
|
+
if (Object.keys(skill).length && !html.includes('</skill-slot>')) {
|
|
171
169
|
this.setState({
|
|
172
|
-
skill:
|
|
170
|
+
skill: undefined,
|
|
173
171
|
templateVisible: false
|
|
174
172
|
});
|
|
173
|
+
this._adapter.notifySkillChange(undefined);
|
|
174
|
+
this._adapter.notifyContentChange([]);
|
|
175
|
+
return;
|
|
176
|
+
} else if (Object.keys(skill).length === 0 && html.includes('</skill-slot>')) {
|
|
177
|
+
const newSkill = findSkillSlotInString(html);
|
|
178
|
+
if ((newSkill === null || newSkill === void 0 ? void 0 : newSkill.value) !== (skill === null || skill === void 0 ? void 0 : skill.value)) {
|
|
179
|
+
this.setState({
|
|
180
|
+
skill: newSkill
|
|
181
|
+
});
|
|
182
|
+
this._adapter.notifySkillChange(newSkill);
|
|
183
|
+
}
|
|
175
184
|
}
|
|
185
|
+
const jsonResult = editor.getJSON();
|
|
186
|
+
const finalResult = transformJSONResult(jsonResult, transformer);
|
|
187
|
+
this._adapter.notifyContentChange(finalResult);
|
|
176
188
|
this.setState({
|
|
177
189
|
content: jsonResult
|
|
178
190
|
});
|
|
@@ -316,6 +328,24 @@ export default class AIChatInputFoundation extends BaseFoundation {
|
|
|
316
328
|
this.handleSend();
|
|
317
329
|
return true;
|
|
318
330
|
}
|
|
331
|
+
if (event.key === 'Enter' && event.shiftKey) {
|
|
332
|
+
/**
|
|
333
|
+
* Tiptap 默认情况下 Enter + Shift 时候是使用 <br /> 实现换行,需要通过新建 p 标签的方式换行保证
|
|
334
|
+
* 自定义的一些逻辑生效(比如零宽字符的插入),因此拦截默认操作,使用新建 p 标签方式
|
|
335
|
+
*/
|
|
336
|
+
event.preventDefault();
|
|
337
|
+
const editor = this._adapter.getEditor();
|
|
338
|
+
if (editor && editor.chain && editor.chain().splitBlock) {
|
|
339
|
+
editor.chain().focus().splitBlock().run();
|
|
340
|
+
} else if (editor && editor.view) {
|
|
341
|
+
const {
|
|
342
|
+
state,
|
|
343
|
+
view
|
|
344
|
+
} = editor;
|
|
345
|
+
view.dispatch(state.tr.split(state.selection.from));
|
|
346
|
+
}
|
|
347
|
+
return true;
|
|
348
|
+
}
|
|
319
349
|
if (event.key !== 'Backspace') return false;
|
|
320
350
|
return false;
|
|
321
351
|
};
|
|
@@ -4,10 +4,10 @@ export interface RichTextJSON {
|
|
|
4
4
|
[key: string]: any;
|
|
5
5
|
}
|
|
6
6
|
export interface BaseSkill {
|
|
7
|
-
icon
|
|
8
|
-
value
|
|
9
|
-
label
|
|
10
|
-
hasTemplate
|
|
7
|
+
icon?: any;
|
|
8
|
+
value?: string;
|
|
9
|
+
label?: string;
|
|
10
|
+
hasTemplate?: boolean;
|
|
11
11
|
[key: string]: any;
|
|
12
12
|
}
|
|
13
13
|
export type Suggestion = string[] | {
|
|
@@ -6,13 +6,19 @@ export declare function transformSelectSlot(obj: any): {
|
|
|
6
6
|
type: string;
|
|
7
7
|
text: any;
|
|
8
8
|
};
|
|
9
|
-
export declare function transformSkillSlot(obj: any):
|
|
9
|
+
export declare function transformSkillSlot(obj: any): {
|
|
10
|
+
type: any;
|
|
11
|
+
value: any;
|
|
12
|
+
};
|
|
10
13
|
export declare function transformInputSlot(obj: any): {
|
|
11
14
|
type: string;
|
|
12
15
|
text: any;
|
|
13
16
|
};
|
|
14
|
-
export declare function transformText(obj: any):
|
|
15
|
-
|
|
17
|
+
export declare function transformText(obj: any): {
|
|
18
|
+
type: string;
|
|
19
|
+
text: any;
|
|
20
|
+
};
|
|
21
|
+
export declare const transformMap: Map<string, any>;
|
|
16
22
|
export declare function transformJSONResult(input: any, customTransformObj?: Map<string, (obj: any) => any>): any[];
|
|
17
23
|
export declare function getCustomSlotAttribute(): {
|
|
18
24
|
default: boolean;
|
|
@@ -21,3 +27,6 @@ export declare function getCustomSlotAttribute(): {
|
|
|
21
27
|
'data-custom-slot': string;
|
|
22
28
|
};
|
|
23
29
|
};
|
|
30
|
+
export declare function findSkillSlotInString(content: string): {
|
|
31
|
+
[k: string]: any;
|
|
32
|
+
};
|
|
@@ -54,19 +54,17 @@ export function transformSelectSlot(obj) {
|
|
|
54
54
|
};
|
|
55
55
|
}
|
|
56
56
|
export function transformSkillSlot(obj) {
|
|
57
|
-
var _a;
|
|
58
57
|
const {
|
|
59
58
|
type,
|
|
60
59
|
attrs
|
|
61
60
|
} = obj;
|
|
62
61
|
const {
|
|
63
|
-
value
|
|
64
|
-
info
|
|
62
|
+
value
|
|
65
63
|
} = attrs;
|
|
66
|
-
return
|
|
64
|
+
return {
|
|
67
65
|
type,
|
|
68
66
|
value
|
|
69
|
-
}
|
|
67
|
+
};
|
|
70
68
|
}
|
|
71
69
|
export function transformInputSlot(obj) {
|
|
72
70
|
var _a, _b;
|
|
@@ -81,9 +79,15 @@ export function transformInputSlot(obj) {
|
|
|
81
79
|
};
|
|
82
80
|
}
|
|
83
81
|
export function transformText(obj) {
|
|
84
|
-
|
|
82
|
+
const {
|
|
83
|
+
text
|
|
84
|
+
} = obj;
|
|
85
|
+
return {
|
|
86
|
+
type: 'text',
|
|
87
|
+
text: text !== strings.ZERO_WIDTH_CHAR ? text : ''
|
|
88
|
+
};
|
|
85
89
|
}
|
|
86
|
-
export const transformMap = new Map([['text', transformText], ['selectSlot', transformSelectSlot], ['inputSlot', transformInputSlot], ['
|
|
90
|
+
export const transformMap = new Map([['text', transformText], ['selectSlot', transformSelectSlot], ['inputSlot', transformInputSlot], ['skillSlot', transformSkillSlot]]);
|
|
87
91
|
export function transformJSONResult(input) {
|
|
88
92
|
let customTransformObj = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : new Map();
|
|
89
93
|
const output = [];
|
|
@@ -126,7 +130,7 @@ export function transformJSONResult(input) {
|
|
|
126
130
|
const lastItem = output[output.length - 1];
|
|
127
131
|
if (lastItem && lastItem.type === 'text') {
|
|
128
132
|
lastItem.text += result.text;
|
|
129
|
-
} else {
|
|
133
|
+
} else if (result.text.length) {
|
|
130
134
|
output.push(result);
|
|
131
135
|
}
|
|
132
136
|
} else {
|
|
@@ -145,4 +149,29 @@ export function getCustomSlotAttribute() {
|
|
|
145
149
|
'data-custom-slot': attributes.isCustomSlot ? 'true' : undefined
|
|
146
150
|
})
|
|
147
151
|
};
|
|
152
|
+
}
|
|
153
|
+
export function findSkillSlotInString(content) {
|
|
154
|
+
const reg = /<skill-slot\s+([^>]*)><\/skill-slot>/i;
|
|
155
|
+
const attrReg = /([\w-]+)=["']?([^"'\s>]+)["']?/g;
|
|
156
|
+
const match = reg.exec(content);
|
|
157
|
+
if (match) {
|
|
158
|
+
const attrsStr = match[1];
|
|
159
|
+
let attrMatch;
|
|
160
|
+
let attrs = {};
|
|
161
|
+
while ((attrMatch = attrReg.exec(attrsStr)) !== null) {
|
|
162
|
+
attrs[attrMatch[1]] = attrMatch[2];
|
|
163
|
+
}
|
|
164
|
+
if (attrs['data-value']) {
|
|
165
|
+
const obj = {
|
|
166
|
+
label: attrs['data-label'],
|
|
167
|
+
value: attrs['data-value'],
|
|
168
|
+
hasTemplate: attrs['data-template'] ? attrs['data-template'] === 'true' : undefined
|
|
169
|
+
};
|
|
170
|
+
return Object.fromEntries(Object.entries(obj).filter(_ref => {
|
|
171
|
+
let [key, value] = _ref;
|
|
172
|
+
return value !== undefined;
|
|
173
|
+
}));
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
return undefined;
|
|
148
177
|
}
|
package/package.json
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@douyinfe/semi-foundation",
|
|
3
|
-
"version": "2.88.0-alpha.
|
|
3
|
+
"version": "2.88.0-alpha.7",
|
|
4
4
|
"description": "",
|
|
5
5
|
"scripts": {
|
|
6
6
|
"build:lib": "node ./scripts/compileLib.js",
|
|
7
7
|
"prepublishOnly": "npm run build:lib"
|
|
8
8
|
},
|
|
9
9
|
"dependencies": {
|
|
10
|
-
"@douyinfe/semi-animation": "2.88.0-alpha.
|
|
11
|
-
"@douyinfe/semi-json-viewer-core": "2.88.0-alpha.
|
|
10
|
+
"@douyinfe/semi-animation": "2.88.0-alpha.7",
|
|
11
|
+
"@douyinfe/semi-json-viewer-core": "2.88.0-alpha.7",
|
|
12
12
|
"@mdx-js/mdx": "^3.0.1",
|
|
13
13
|
"async-validator": "^3.5.0",
|
|
14
14
|
"classnames": "^2.2.6",
|
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
"*.scss",
|
|
30
30
|
"*.css"
|
|
31
31
|
],
|
|
32
|
-
"gitHead": "
|
|
32
|
+
"gitHead": "47f25be3aae3674564e030e0aec1daec2615abd8",
|
|
33
33
|
"devDependencies": {
|
|
34
34
|
"@babel/plugin-transform-runtime": "^7.15.8",
|
|
35
35
|
"@babel/preset-env": "^7.15.8",
|