Skip to content

Commit f3c5d37

Browse files
authored
feat: [AIChatInput] Newly added sendHotKey API (#3099)
1 parent 05efd0c commit f3c5d37

File tree

7 files changed

+38
-6
lines changed

7 files changed

+38
-6
lines changed

content/ai/aiChatInput/index-en-US.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1501,6 +1501,7 @@ render(<CustomRichTextExtension />);
15011501
| onBlur | Callback when input blurs | (event: React.FocusEvent) => void | - |
15021502
| onConfigureChange | Callback for configuration area changes | (value: LeftMenuChangeProps, changedValue: LeftMenuChangeProps) => void | - |
15031503
| onFocus | Callback when input focused | (event: React.FocusEvent) => void | - |
1504+
| sendHotKey | Keyboard shortcut for sending content, supports `enter` \| `shift+enter`. The former will send the message in the input box when you press enter alone. When the shift and enter keys are pressed at the same time, it will only wrap the line and not send it. The latter is the opposite | string | `enter` |
15041505
| showReference | Show reference area | boolean | true |
15051506
| showTemplateButton | Show template button | boolean | false |
15061507
| showUploadFile | Show upload file area | boolean | true |

content/ai/aiChatInput/index.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1579,6 +1579,7 @@ render(<CustomRichTextExtension />);
15791579
| onBlur | 富文本输入框失焦的回调 | (event: React.FocusEvent) => void | - |
15801580
| onConfigureChange | 配置区域发生变化的回调 | (value: LeftMenuChangeProps, changedValue: LeftMenuChangeProps) => void | - |
15811581
| onFocus | 富文本输入框聚焦的回调 | (event: React.FocusEvent) => void | - |
1582+
| sendHotKey | 发送输入内容的键盘快捷键,支持 `enter` \| `shift+enter`。前者在单独按下 enter 将发送输入框中的消息, shift 和 enter 按键同时按下时,仅换行,不发送。后者相反 | string | `enter` |
15821583
| showReference | 是否展示引用区域,用于配合 renderTopSlot 使用 | boolean | true |
15831584
| showTemplateButton | 是否展示模板按钮,未设置时,将根据当前选中技能中的 hasTemplate 决定是否展示模版按钮 | boolean | false |
15841585
| showUploadFile | 是否展示上传文件区域,用于配合 renderTopSlot 使用 | boolean | true |

packages/semi-foundation/aiChatInput/constants.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,11 @@ const strings = {
1010
ZERO_WIDTH_CHAR: '\uFEFF',
1111
PIC_PREFIX: 'image/',
1212
PIC_SUFFIX_ARRAY: ['png', 'jpg', 'jpeg', 'gif', 'bmp', 'webp'],
13-
DELETABLE: 'skipCustomTransactionPlugin'
13+
DELETABLE: 'skipCustomTransactionPlugin',
14+
SEND_HOTKEY: {
15+
'ENTER': 'enter' as const,
16+
'SHIFT_ENTER': 'shift+enter' as const,
17+
}
1418
};
1519

1620
const numbers = {

packages/semi-foundation/aiChatInput/foundation.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import BaseFoundation, { DefaultAdapter } from '../base/foundation';
22
import { Attachment, BaseSkill, Suggestion, Reference, Content, LeftMenuChangeProps, MessageContent } from './interface';
33
import { get, isNumber, isString } from 'lodash';
4-
import { cssClasses } from './constants';
4+
import { cssClasses, strings } from './constants';
55
import { findSkillSlotInString, getSkillSlotString, transformJSONResult } from './utils';
66

77
export interface AIChatInputAdapter<P = Record<string, any>, S = Record<string, any>> extends DefaultAdapter<P, S> {
@@ -338,6 +338,7 @@ export default class AIChatInputFoundation extends BaseFoundation<AIChatInputAda
338338

339339
handRichTextArealKeyDown = (view: any, event: KeyboardEvent) => {
340340
// console.log('outer key down handle');
341+
const { sendHotKey } = this.getProps();
341342
const { suggestionVisible, skillVisible } = this.getStates();
342343
/**
343344
* 当建议/技能面板可见时候,上下按键,enter 按键被用于操作面板选项的 active 项,或做选中操作的,
@@ -351,11 +352,11 @@ export default class AIChatInputFoundation extends BaseFoundation<AIChatInputAda
351352
}
352353
const editor = this._adapter.getEditor() ?? {};
353354
const allowHotKeySend = get(editor, 'storage.SemiAIChatInput.allowHotKeySend');
354-
if (event.key === 'Enter' && !event.shiftKey && allowHotKeySend) {
355+
if (event.key === 'Enter' && (sendHotKey === strings.SEND_HOTKEY.ENTER ? !event.shiftKey : event.shiftKey) && allowHotKeySend) {
355356
this.handleSend();
356357
return true;
357358
}
358-
if (event.key === 'Enter' && event.shiftKey) {
359+
if (event.key === 'Enter' && (sendHotKey === strings.SEND_HOTKEY.ENTER ? event.shiftKey : !event.shiftKey)) {
359360
/**
360361
* Tiptap 默认情况下 Enter + Shift 时候是使用 <br /> 实现换行
361362
* 为保证自定义的一些逻辑生效(比如零宽字符的插入),Enter + Shift 希望实现通过新建 p 标签的方式完成换行

packages/semi-ui/aiChatInput/_story/aiChatInput.stories.jsx

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -679,3 +679,26 @@ export const SetContent = () => {
679679
>点我查看富文本区域内容</Button>
680680
</>);
681681
}
682+
683+
export const SendHotkeyDemo = () => {
684+
const [generating, setGenerating] = useState(false);
685+
686+
const onUploadChange = useCallback((fileList) => {
687+
console.log('onUploadChange', fileList);
688+
}, []);
689+
690+
const toggleGenerate = useCallback((props) => {
691+
setGenerating(value => !value);
692+
}, []);
693+
694+
return (<AIChatInput
695+
sendHotKey='shift+enter'
696+
generating={generating}
697+
placeholder={'输入内容或者上传内容'}
698+
uploadProps={uploadProps}
699+
onUploadChange={onUploadChange}
700+
style={outerStyle}
701+
onMessageSend={toggleGenerate}
702+
onStopGenerate={toggleGenerate}
703+
/>);
704+
}

packages/semi-ui/aiChatInput/index.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import React from 'react';
33
import BaseComponent from '../_base/baseComponent';
44
import { AIChatInputProps, AIChatInputState, Skill, Attachment, Reference, Content, LeftMenuChangeProps } from './interface';
55
import { noop, isEqual } from 'lodash';
6-
import { cssClasses, numbers } from '@douyinfe/semi-foundation/aiChatInput/constants';
6+
import { cssClasses, numbers, strings } from '@douyinfe/semi-foundation/aiChatInput/constants';
77
import { Popover, Tooltip, Upload, Progress } from '../index';
88
import { IconSendMsgStroked, IconFile, IconCode, IconCrossStroked,
99
IconPaperclip, IconArrowUp, IconStop, IconClose, IconTemplateStroked,
@@ -54,6 +54,7 @@ class AIChatInput extends BaseComponent<AIChatInputProps, AIChatInputState> {
5454
dropdownMatchTriggerWidth: true,
5555
round: true,
5656
topSlotPosition: 'top',
57+
sendHotKey: strings.SEND_HOTKEY.ENTER,
5758
}
5859

5960
constructor(props: AIChatInputProps) {

packages/semi-ui/aiChatInput/interface.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,8 @@ export interface AIChatInputProps {
7878
// transformer
7979
transformer?: Map<string, (obj: any) => any>;
8080
// Popover related
81-
popoverProps?: PopoverProps
81+
popoverProps?: PopoverProps;
82+
sendHotKey?: 'enter' | 'shift+enter'
8283
}
8384

8485
export interface RenderSuggestionItemProps {

0 commit comments

Comments
 (0)