- 前端
- UI组件
- AI 应用
【免费下载链接】MateChat
前端智能化场景解决方案UI库,轻松构建你的AI应用,我们将持续完善更新,欢迎你的使用与建议。 官网地址:https://matechat.gitcode.com
MateChat 是为前端智能化场景提供 UI 解决方案的组件库,其 Angular 版本(@matechat/ng)中的 Input 组件是对话式应用的核心交互入口,负责承载用户提问、控制发送行为,并支持主题标签、格式化输入等结构化内容录入。本篇指南基于 MateChat 仓库中 Input 组件的官方文档与源码实现,完整覆盖基本用法、展示形态、提交快捷键、自动高度调整、自定义发送按钮与formatContentOptions格式化编排等全部能力,帮助你在 Angular 项目中快速搭建一个功能完整的 AI 对话输入区,并理解其背后的渲染与事件机制。
组件概览与引入
Input 组件的模板选择器为mc-input,通过InputModule按需引入:
import { InputModule } from '@matechat/ng';在 standalone 组件中将其加入imports数组即可使用。模块定义见 input.module.ts,内部聚合了InputComponent、ButtonComponent、SendIconComponent、InputTagComponent与EditableBlockComponent等子组件。
组件主体结构(input.component.ts)定义了全部对外输入参数,默认值如下:
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
value | string | '' | 输入框的值,纯文本展示 |
formatContentOptions | FormatContentOptions | {} | 输入框中需要被格式化录入的值及其配置项,与value互斥,两者选其一 |
placeholder | string | -- | 输入框占位文字 |
disabled | boolean | false | 是否禁用输入框 |
displayType | DisplayType | 'full' | 输入框的展示形态 |
loading | boolean | false | 是否发送中,为true时点击发送按钮可暂停回答 |
showCount | boolean | false | 是否显示字数统计 |
maxLength | number | -- | 输入框的最大字数 |
submitShortKey | SubmitShortKey \| null | 'enter' | 发送快捷键,null表示不使用快捷键发送 |
variant | InputVariant | 'bordered' | 输入框边框形态 |
sendBtnVariant | SendBtnVariant | 'full' | 发送按钮的形态 |
autofocus | boolean | false | 是否自动聚焦输入框 |
autosize | TextareaAutoSize | false | 是否自动调整文本域高度 |
注意:
value与formatContentOptions互斥,二者选其一。当使用formatContentOptions时,组件内部会切换到可编辑块(mc-editable-block)渲染模式。
基本用法
绑定value等基本参数即可使用,通过change/submit/cancel事件接收用户操作。仓库内置的基础示例(basic-demo.component.html)演示了带字数统计与加载态的完整用法:
<mc-input [value]="inputValue" [maxLength]="2000" [showCount]="true" [loading]="loading" (change)="onInputChange($event)" (submit)="onSubmit($event)" (cancel)="onCancel()" ></mc-input>对应的组件逻辑(basic-demo.component.ts):
onInputChange(e) { console.log('input change---', e); } onSubmit(e) { this.loading = true; // 进入“发送中”状态 console.log('input submit---', e); } onCancel() { this.loading = false; // 暂停回答后恢复 console.log('input cancel'); }loading为true时,发送按钮会变为“停止回答”形态,点击触发cancel事件;showCount开启后会在底部区域显示当前字数/最大字数统计(见 input.component.html)。
展示形态
displayType参数控制输入框的布局形态,支持的值为full和simple,默认为full:
full形态:prefix 插槽和输入框在同一行,extra 插槽和发送按钮在下方(底部区域还可承载字数统计)。simple形态:prefix 插槽、输入框和发送按钮在同一行,不支持 extra 插槽。
variant参数可设置为borderless,渲染不带边框的输入框;sendBtnVariant控制发送按钮形态,支持的值为full(圆角按钮,同时显示图标和文字)与simple(圆形按钮,仅显示图标),默认为full。
仓库示例(suffix-demo.component.html)组合了三种参数并自定义了 suffix 内容:
<mc-input [value]="inputValue" [displayType]="DisplayType.Simple" [variant]="InputVariant.BorderLess" [sendBtnVariant]="SendBtnVariant.Simple" [loading]="loading" (submit)="onSubmit($event)" > <ng-template #suffix> <div class="input-prefix-wrap"> <i class="icon-appendix"></i> </div> </ng-template> </mc-input>相关枚举定义见 types.ts:
enum DisplayType { Simple = 'simple', // prefix插槽、输入框和发送按钮在同一行,不支持extra插槽 Full = 'full', // prefix插槽和输入框在同一行,extra插槽和发送按钮在下方 } enum InputVariant { Bordered = 'bordered', BorderLess = 'borderless', } enum SendBtnVariant { Simple = 'simple', // 圆形按钮,仅显示图标,不显示文字 Full = 'full', // 圆角按钮,同时显示图标和文字 }从源码结构看,形态参数最终被映射为根元素上的 CSS 类:getInputClasses(foundation.ts)会根据disabled、displayType、variant生成mc-input-disabled、mc-input-simple、mc-input-borderless等类名,模板中displayType === 'full'时才渲染包含 extra 插槽与字数统计的mc-input-foot底部区域。
提交模式
submitShortKey设置提交快捷键,支持的值为enter和shiftEnter,默认为enter;设为null则完全禁用快捷键发送。两种模式下的换行行为互为镜像:
- 提交快捷键为
enter时,换行快捷键为shift+enter; - 提交快捷键为
shiftEnter时,换行快捷键为enter。
enum SubmitShortKey { Enter = 'enter', ShiftEnter = 'shiftEnter', }仓库示例(submit-demo.component.html)演示了shiftEnter提交模式:
<mc-input [value]="inputValue" [loading]="loading" submitShortKey="shiftEnter" (submit)="onSubmit($event)" ></mc-input>快捷键判定逻辑集中在 foundation.ts 的 onKeydown 中:当submitShortKey为null时直接返回;Enter模式下要求!event.shiftKey,shiftEnter模式下要求event.shiftKey,命中后调用preventDefault、触发submit(inputValue)并清空输入值。此外,若未提供placeholder,组件会自动生成包含快捷键提示的默认占位文案(如“请输入您的问题,并按 Enter 发送,按 Shift + Enter 换行”),其文案通过Input.pleaseEnterPlaceholder国际化 key 生成(见 foundation.ts),因此提示文案会跟随submitShortKey配置自动切换。
在可编辑块模式下,对应的判定逻辑实现在 editable-block.component.ts 的 handleDivKeydown,且发送前会校验maxLength,超长内容不会发出(见 handleSend)。
自动聚焦
通过autofocus属性设置输入框在组件挂载后自动获得焦点,默认为false;当输入框被禁用时,自动聚焦不会生效。
<mc-input [value]="inputValue" [autofocus]="true" ...></mc-input>源码层面(input.component.ts),聚焦动作发生在ngAfterViewInit中,并且用一个setTimeout延迟到下一个宏任务执行,以确保视图(textarea)已完全初始化后再调用focus(),同时显式判断!this.disabled以满足“禁用时不聚焦”的约束。
自动调整高度
autosize属性让文本域自动调整高度,支持布尔值和配置对象两种形式:
- 设置为
true:使用默认配置(最小 1 行,最大 5 行); - 设置为对象:可自定义最小和最大行数,如
{ minRows: 2, maxRows: 10 }; - 设置为
false(默认):高度固定。
type TextareaAutoSize = { minRows?: number; maxRows?: number } | boolean;minRows?: number:最小行数,默认为 1maxRows?: number:最大行数,默认为 5
仓库示例(auto-size-demo.component.html)同时演示了三种形态:
<mc-input [value]="inputValue1" [autosize]="true" placeholder="默认自动调整(最小1行,最大5行)"></mc-input> <mc-input [value]="inputValue2" [autosize]="{ minRows: 2, maxRows: 10 }" placeholder="自定义行数范围"></mc-input> <mc-input [value]="inputValue3" [autosize]="false" placeholder="固定高度的文本域"></mc-input>实现细节值得注意:updateTextareaStyle 在输入、value变化、autosize变化以及视图初始化时都会重新计算高度;而 computeTextareaHeight 采用“影子 textarea”方案——在页面中动态创建一个隐藏 textarea,继承line-height、font-size、padding等影响排版的全部样式,测量scrollHeight得到真实内容高度,再按minRows/maxRows计算单行高度(扣除 padding)得出minHeight/maxHeight钳制区间;超出最大高度时会设置overflowY: auto让内容可滚动,最终统一附加resize: none禁止手动拖拽。
自定义发送按钮
通过button插槽自定义发送按钮,可实现按钮的 disable、loading 等状态以及按钮图标、文案的自定义。仓库示例(button-demo.component.html):
<mc-input [value]="inputValue" [maxLength]="2000" [loading]="loading" (change)="onInputChange($event)" (submit)="onSubmit($event)" (cancel)="onCancel()"> <ng-template #button> <div class="my-button" [class.disabled]="!loading && !inputValue" (click)="onConfirm()"> <span class="mc-button-content"> <span>{{ loading ? '停止' : '发送' }}</span> </span> </div> </ng-template> </mc-input>自定义按钮需要自行处理两种状态:loading为true时点击应触发取消(onCancel),否则发送inputValue并清空内容(见 button-demo.component.ts)。如果不提供button插槽,组件会使用默认按钮(button.component.ts),其内部已实现同样的状态机:onConfirm中判断loading则cancel.emit(),否则submit.emit(inputValue)并清空(见 button.component.ts)。按钮禁用条件为disabled || (!loading && !inputValue),即空内容且非发送中时不可发送(见 input.component.html)。
插入主题标签
通过ThemeTagItem类型配置前置主题标签,支持自定义主题标签的文本内容、pop 弹出提示内容等。约束条件:
- 当前仅支持最多设置一个 ThemeTag,且必须放在
formatContent数组的第一个位置; - 可通过
themeTag插槽自定义主题标签的展示效果。
interface ThemeTagItem { type: 'themeTag'; // 固定type themeTagKey: string; // 主题标签的唯一标识 themeTagText: string; // 主题标签的文本内容 clearInput?: boolean; // 关闭主题标签时是否清空输入框中在其后面内容,默认为false popoverContent: string; // 主题标签的pop提示文案 }仓库示例(theme-tag-demo.component.ts)演示了动态插入与关闭主题标签:
openThemeTag() { this.formatContentOptions = { formatContent: [ { type: 'themeTag', themeTagKey: 'themeTag', // 主题标签的唯一标识 themeTagText: '动图生成', // 主题标签的文本内容 clearInput: false, // 关闭主题标签时是否清空对应输入框内容 popoverContent: '点击退出技能', // 主题标签的pop弹出提示内容 }, ], }; } closeThemeTag() { this.formatContentOptions = { formatContent: [] }; }展示效果通过themeTag插槽自定义(theme-tag-demo.component.html):
<mc-input [formatContentOptions]="formatContentOptions" placeholder="请输入您的问题,并按Enter发送,按Shift + Enter换行" (change)="onInputChange($event)" (submit)="onSubmit($event)"> <ng-template #themeTag let-themeTagText="themeTagText"> <span class="tip-tag-custom"> <i class="icon-code-editor-close"></i> <span class="tip-tag-icon icon-default"></span> <span class="ai-input-prefix">{{themeTagText}}</span> </span> </ng-template> </mc-input>从源码结构看,当ngOnChanges检测到formatContentOptions变化时,组件会过滤出themeTag类型的项并调用openTipTag,其余格式化项交给setMixTags(input.component.ts);主题标签关闭时,若配置了clearInput: true,closeTipTag 会连带清空输入框内容。值得注意的是一处取值细节:getInput返回的内容会主动剔除主题标签前缀文本(见 getCurrentInputValue),因此submit/change事件拿到的是用户真正输入的部分,主题标签本身不会混入提交内容。
插入格式化 Input 标签
通过FormatInputItem类型配置一个 input 标签,实现对输入框内某些局部文本的默认填充或占位提示;input 标签可以插入多个,且插入位置不固定:
interface FormatInputItem { type: 'input'; // 固定type key: string; // 标签的唯一标识 placeholder: string; // input标签的占位提示内容 content?: string; // input标签的默认展示内容 }仓库示例(format-input-demo.component.ts)用“text + input”交替编排出一个“论文写作”提示句:
this.formatContentOptions = { formatContent: [ { key: '', type: 'text', content: '我是', placeholder: '' }, { key: 'input1', type: 'input', placeholder: '请输入专业', content: '计算机科学' }, { key: '', type: 'text', content: '专业的本科生,帮我写一篇关于', placeholder: '' }, { key: 'input2', type: 'input', placeholder: '请输入主题', content: '' }, { key: '', type: 'text', content: '的论文。', placeholder: '' }, ], };渲染后,content有值的 input 标签展示为可编辑的默认内容(“计算机科学”),无content的则展示placeholder(“请输入主题”),用户可直接在这些局部片段上输入,从而限定其主题、类型、范围等。
多种格式化内容自定义编排
通过FormatContentOptions.formatContent中多种格式化标签的自定义组合编排,按需实现对输入框内文本的多种格式化展示:
interface FormatContentOptions { formatContent: FormatContentItem[]; } type FormatContentItem = FormatTextItem | FormatInputItem | ThemeTagItem;interface FormatTextItem { type: 'text'; // 固定type key: string; // 标签的唯一标识 content: string; // 文本内容 }仓库示例(format-content-demo.component.ts)将主题标签、固定文本、两个 input 标签编排为一条完整的“宣传文案生成”指令:
const mixTags = [ { type: 'themeTag', themeTagKey: 'themeTag', themeTagText: '文章生成', clearInput: true, popoverContent: '点击关闭主题' }, { key: '', type: 'text', content: '帮我写一篇面向', placeholder: '' }, { key: 'input1', type: 'input', placeholder: '输入目标人群', content: '职场人士' }, { key: '', type: 'text', content: '关于', placeholder: '' }, { key: 'input2', type: 'input', placeholder: '输入产品', content: '' }, { key: '', type: 'text', content: '的宣传文案,需要直击痛点,吸引用户点击。', placeholder: '' }, ]; this.formatContentOptions = { formatContent: mixTags };编排规则可归纳为:themeTag(可选,至多一个且必须位于首位)+ 任意数量、任意顺序的text与input交错排列。一旦formatContent非空,组件即切换到showEditableBlock模式,由mc-editable-block(contenteditable div)负责渲染,而非原生 textarea。
自定义插槽
Input 组件提供以下插槽,覆盖输入框的顶部、左侧、右侧、底部与按钮区域:
| 插槽名 | 说明 |
|---|---|
head | 自定义输入框顶部的内容 |
prefix | 自定义输入框左侧的内容 |
suffix | 自定义输入框右侧的内容 |
extra | 自定义发送按钮左侧的内容,仅在displayType='full'时生效 |
button | 自定义输入框的发送按钮 |
themeTag | 自定义前置主题标签的展示效果 |
仓库示例(slot-demo.component.html)演示了head(顶部附件列表)与extra(底部“智能体/附件”入口)的组合:
<mc-input [value]="inputValue" [loading]="loading" (submit)="onSubmit($event)"> <ng-template #head> <div class="appendix-wrap"> <div class="appendix-item"> <span>README.md</span> <i class="icon-code-editor-close"></i> </div> </div> </ng-template> <ng-template #extra> <div class="input-foot-left"> <span><i class="icon-at"></i>智能体</span> <span><i class="icon-appendix"></i>附件</span> </div> </ng-template> </mc-input>插槽模板通过@ContentChild声明式收集(input.component.ts),在模板中按需投影。
事件与方法
事件(均在 input.component.ts 中声明):
| 事件名 | 类型 | 说明 |
|---|---|---|
change | (e: string) => void | 输入内容变化时触发,返回当前输入内容 |
submit | (e: string) => void | 发送时触发,返回当前输入内容 |
cancel | () => void | 状态为发送中、点击暂停回答按钮时触发 |
focus | (e: FocusEvent) => void | 聚焦输入框时触发 |
blur | (e: FocusEvent) => void | 输入框失焦时触发 |
公开方法:
| 方法名 | 类型 | 说明 |
|---|---|---|
clearInput | () => void | 清空输入框的内容 |
getInput | () => string | 获取输入框的内容 |
两者在可编辑块模式下会委托给mc-editable-block处理(input.component.ts),保证两种渲染模式下行为一致。
交互细节与实现要点
结合源码实现,还有几个影响实际集成体验的细节:
- 中文输入法兼容:textarea 模式通过
compositionstart/compositionend维护lock标志,组合输入期间不重复触发change,仅在compositionend时统一发射(input.component.ts),可编辑块模式同样用isComposing做了相同处理,避免拼音中间态污染内容。 - 清空即还原:可编辑块模式下,当输入内容被全部删除为空时,
handleDivInput会延迟一个渲染周期(TimeToViewRender = 50ms,定义于 types.ts)后切回普通 textarea 模式(input.component.ts),让空输入回到轻量渲染路径。 - 焦点导航:可编辑块对方向键与 Backspace/Delete 做了专门处理,光标抵达相邻 input 标签边界时会把焦点移入该标签内部编辑;空标签在 Backspace/Delete 下会被整体移除(editable-block.component.ts)。
- 禁用态守卫:
setMixTags、openTipTag、closeTipTag以及EditableBlock的所有写入方法(setMixTags/setText/setInputTag)都会先判断disabled,禁用状态下任何格式化编排调用都会被忽略。 - 国际化占位:未设置
placeholder时,默认占位文案中的快捷键提示(Enter / Shift + Enter)会随submitShortKey自动切换,且经由LocaleService的Input.pleaseEnterPlaceholderkey 输出,支持中英文环境。
总结
MateChat NG 的 Input 组件围绕“对话输入”这一场景做了完整封装:value+ 事件体系覆盖常规受控输入,displayType/variant/sendBtnVariant适配不同页面形态,submitShortKey精确控制回车/Shift+Enter 的提交与换行语义,autosize提供基于影子 textarea 的高度自适应,button插槽与loading状态机支持“发送/停止”双态按钮;而formatContentOptions的 ThemeTag/Text/Input 三类标签编排能力,则让输入框能够承载“主题 + 模板化提示 + 可编辑片段”的结构化提问。以上所有能力均可在 Input 组件源码 与 内置示例 中对照验证,便于按需在自有 Angular 项目中落地。
- 前端
- UI组件
- AI 应用
【免费下载链接】MateChat
前端智能化场景解决方案UI库,轻松构建你的AI应用,我们将持续完善更新,欢迎你的使用与建议。 官网地址:https://matechat.gitcode.com
相关推荐
rsuite Input 输入框组件完全指南:从基础用法、输入框组合到掩码输入
rsuite Input 输入框组件完全指南:从基础用法、输入框组合到掩码输入 本指南以 rsuite 文档站 docs/pages/components/in
前端UI组件rsuite Input 输入框组件完全指南:从基础用法到 MaskedInput 掩码输入
rsuite Input 输入框组件完全指南:从基础用法到 MaskedInput 掩码输入 导读 rsuite 的 <Input 组件用于接收和展示用户的单行
前端UI组件MateChat NG Bubble 气泡组件全解:从 content 基础用法到头像、插槽与样式定制
MateChat NG Bubble 气泡组件全解:从 content 基础用法到头像、插槽与样式定制 MateChat NG 的 Bubble (气泡)组件是
前端UI组件AI 应用
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考