tencent cloud

Chat

News and Announcements
Release Notes
Announcements
Product Introduction
Overview
Basic Concepts
Scenarios
Features
Account System
User Profile and Relationship Chain
Message Management
Group Related
Official Account
Audio/Video Call
Use Limits
Purchase Guide
Billing Overview
Pricing
Purchase Instructions
Renewal Guide
Service Suspension Explanation
Refund Policy
Development Guidelines
Demo Zone
Activate Service
Free Demos
Quick Run
Download
SDK and Demo Source Code
Update Log
Chat Interaction (UI Included)
TUIKit Introduction
Getting Started
Full-feature Integration
Single-function Integration
Build with AI
Build Basic Interfaces
More Features
Customizing Appearance
Internationalization
Push Service
Overview
Noun explanation
Activate the Service
Quick Start
Manufacturer Channel
Statistics
Troubleshooting Tool
Client APIs
REST API
Push Callback
Advanced Features
Release Notes
Error Codes
FAQS
Desk
Overview
Quick Start
Integration Guide
Admin Operation Manual
Agent Manual
More Practices
Live Streaming Setup Guide
AI Chatbot
Super Large Entertainment and Collaboration Community
Discord Implementation Guide
How to Integrate Chat into Games
WhatsApp Channel-style Official Account Integration Solution
Send Red Packet
Firewall Restrictions
No UI Integration
Quick Start
SDK Integration
Initialization
Login and Logout
Message
Conversation
Group
Community Topic
User Profile and Relationship Chain
Offline Push
Cloud Search
Local Search
Official Channel Management
Client APIs
JavaScript
Android
iOS & macOS
Swift
Flutter
Electron
Unity
React Native
C APIs
C++
Server APIs
Secure authentication with UserSig
RESTful APIs
Webhooks
Console Guide
New Console Introduction
Creating and Upgrading an Application
Basic Configuration
Feature Configuration
Account Management
Group Management
Official Channel Management
Webhook Configuration
Usage
Viewing Guide for Resource Packages
Real-Time Monitor
Auxiliary Development Tools
Access Management
Advanced Features
FAQs
uni-app FAQs
Purchase
SDK
Account Authentication
User Profile and Relationship Chain
Message
Group
Audio-Video Group
Nickname and Profile Photo
Security Compliance Certification
Service Level Agreement
Security Compliance Certification
Chat Policies
Privacy Policy
Data Privacy and Security Agreement
Migration
Migration Solutions
Migration Solutions Lite
Error Codes
Contact Us

React

PDF
Focus Mode
Font Size
Last updated: 2026-03-04 15:57:13

Overview

MessageInput is a fully functional message input component, providing core chat input features such as text editing, emoji selection, file attachment, and send button. It supports various custom options, including input behavior configuration, toolbar customization, component replacement, and slot expansion, meeting the personalized requirements of different chat scenarios.

Props

Field
Type
Default Value
Description
autoFocus
boolean
true
Whether to auto-focus into the input box
disabled
boolean
false
Whether to disable the input component
boolean
false
Whether to hide the send button
string
''
Input box placeholder text
className
string
undefined
Root container custom CSS class name
style
React.CSSProperties
undefined
Root container custom inline style
'collapsed' | 'expanded'
'collapsed'
Attachment selector display mode
actions
MessageInputActions
['EmojiPicker', 'AttachmentPicker']
Toolbar action button configuration
slots
MessageInputSlots
undefined
Slot Configuration Object
JSX.Element
undefined
Custom Text Editor Component
JSX.Element
undefined
Custom Emoji Selector Component
JSX.Element
undefined
Custom Attachment Selector Component
JSX.Element
undefined
Custom File Selector Component
JSX.Element
undefined
Custom Image Selector Component
JSX.Element
undefined
Custom Video Selector Component

Prop Explanation

autoFocus

type: boolean
autoFocus is used to set whether to auto-focus into the input box when mounting, default value is true.

disabled

type: boolean
disabled is used to set whether to disable the entire input component, including text input and all operation buttons, default value is false.

hideSendButton

type: boolean
hideSendButton is used to set whether to hide the send button, suitable for scenarios where custom send trigger mode is needed, default value is false.

placeholder

type: string
placeholder is used to set the placeholder text for the input box, default value is an empty string.

className

type: string
className is used to set the custom CSS class name for the root container, default value is undefined.

style

type: React.CSSProperties
style is used to set the custom inline style for the root container, default value is undefined.

attachmentPickerMode

type: 'collapsed' | 'expanded'
attachmentPickerMode is used to set the display mode of the attachment selector, default value is 'collapsed'.
collapsed: Collapse mode, unfold options after clicking
expanded: Expanded mode, display all options directly
Note:
By default, AttachmentPicker refers to the attachment selector, including file selection, image selection, and video selection.
1. When the attachmentPickerMode is "collapsed", click the attachment selector to pop up a menu displaying file selection, image selection, and video selection.
2. When attachmentPickerMode is "expanded", the attachment selector expands by default, displaying file selection, image selection, and video selection in tile display.

actions

type: MessageInputActions
Actions for configuration toolbar display action buttons, default value ['EmojiPicker', 'AttachmentPicker'].
type BuiltInAction =
| 'EmojiPicker'
| 'ImagePicker'
| 'FilePicker'
| 'VideoPicker'
| 'AttachmentPicker';

type CustomAction = {
key: string;
label?: string | undefined;
component?: React.ComponentType<any> | undefined;
className?: string | undefined;
style?: React.CSSProperties | undefined;
iconSize?: number | undefined;
};

type MessageInputActions = Array<BuiltInAction | CustomAction>;

Example1: Customizing Toolbar Button Sequence

import { Chat, MessageInput } from '@tencentcloud/chat-uikit-react';

function ChatWithCustomActions() {
// Custom button sequence: file, image, video, emoji
const customActions = ['FilePicker', 'ImagePicker', 'VideoPicker', 'EmojiPicker'];
return (
<Chat>
<MessageInput actions={customActions} />
</Chat>
);
}
The rendering is shown in the figure below:


Example 2: Adding Custom Action Buttons - Customer Service System Quick Reply

import { Chat, MessageInput, useMessageInputState } from '@tencentcloud/chat-uikit-react';

// Quick reply component
function QuickReplyPicker() {
const { setContent } = useMessageInputState();
const quickReplies = [
'Hello, happy to serve you!',
'Please wait, I will check for you...',
'Thank you for your consultation, any other issues?',
The issue has been resolved. Have a pleasant life!,
];

const handleQuickReply = (text: string) => {
setContent(text);
};

return (
<div style={{ position: 'relative' }}>
<button title="quick reply"></button>
<div style={{
position: 'absolute',
bottom: '100%',
left: 0,
background: 'white',
border: '1px solid #ccc',
borderRadius: '4px',
padding: '8px',
minWidth: '200px'
}}>
{quickReplies.map((reply, index) => (
<div
key={index}
onClick={() => handleQuickReply(reply)}
style={{
padding: '4px 8px',
cursor: 'pointer',
borderRadius: '2px'
}}
>
{reply}
</div>
))}
</div>
</div>
);
}

function CustomerServiceChat() {
const actions = [
{
key: 'quickReply',
label: 'quick reply',
component: QuickReplyPicker
},
'EmojiPicker',
'FilePicker'
];
return (
<Chat>
<MessageInput actions={actions} />
</Chat>
);
}
The rendering is shown in the figure below:


slots

type: MessageInputSlots
Slots are used to insert custom content at specific locations in the input component, default value is undefined.
interface MessageInputSlots {
headerToolbar?: () => React.ReactNode;
footerToolbar?: () => React.ReactNode;
leftInline?: () => React.ReactNode;
rightInline?: () => React.ReactNode;
inputPrefix?: () => React.ReactNode;
inputSuffix?: () => React.ReactNode;
}
MessageInput architecture diagram
MessageInput architecture diagram


Example 1: Adding Message Statistics Display

import { Chat, MessageInput, useMessageInputState } from '@tencentcloud/chat-uikit-react';

function ChatWithMessageStats() {
const { inputRawValue } = useMessageInputState();
// Header toolbar: Display character statistics
const HeaderToolbar = () => !inputRawValue
? null
: (
<div style={{
padding: '4px 12px',
fontSize: '12px',
color: '#666',
borderBottom: '1px solid #eee',
}}
>
Character count:
{' '}
{inputRawValue?.reduce((acc, item) => acc + (item.type === 'text' ? item.content.length : 1), 0) || 0}
/500
</div>
);

// toolbar: display sending notification
const FooterToolbar = () => (
<div style={{
padding: '4px 12px',
fontSize: '12px',
color: '#999',
textAlign: 'right'
}}>
Press Ctrl+Enter to enter a new line
</div>
);

return (
<Chat>
<MessageInput
slots={{
headerToolbar: HeaderToolbar,
footerToolbar: FooterToolbar
}}
/>
</Chat>
);
}
The rendering is shown in the figure below:


Example 2: Input Box Prefix/Suffix Feature

import { Chat, MessageInput } from '@tencentcloud/chat-uikit-react';

function ChatWithInputPrefixSuffix() {
// Input box prefix: @reminder feature
const InputPrefix = () => (
<button
style={{
border: 'none',
background: 'transparent',
color: '#1890ff',
cursor: 'pointer'
}}
onClick={() => {
// Trigger @user selection
console.log('toggle on @user selection')
}}
>
@
</button>
);

// Input box suffix: voice input
const InputSuffix = () => (
<button
style={{
border: 'none',
background: 'transparent',
cursor: 'pointer'
}}
onClick={() => {
// Start voice input
console.log('start voice input')
}}
>
🎤
</button>
);

return (
<Chat>
<MessageInput
slots={{
inputPrefix: InputPrefix,
inputSuffix: InputSuffix
}}
/>
</Chat>
);
}
The rendering is shown in the figure below:


Example 3: Fully Customizing the Toolbar on Both Sides

import { Chat, MessageInput } from '@tencentcloud/chat-uikit-react';

function ChatWithCustomToolbars() {
// Left-side toolbar: only retain emoji and images
const LeftInline = () => (
<div style={{ display: 'flex', gap: '8px' }}>
<button>😊</button>
<button>📷</button>
</div>
);

// toolbar on the right: custom sending area
const RightInline = () => (
<div style={{ display: 'flex', alignItems: 'center', gap: '8px' }}>
<span style={{ fontSize: '12px', color: '#666' }}>
Enter
</span>
<button
style={{
padding: '6px 12px',
background: '#1890ff',
color: 'white',
border: 'none',
borderRadius: '4px',
cursor: 'pointer'
}}
>
Send
</button>
</div>
);

return (
<Chat>
<MessageInput
slots={{
leftInline: LeftInline,
rightInline: RightInline
}}
/>
</Chat>
);
}
The rendering is shown in the figure below:


TextEditor

type: JSX.Element
TextEditor is used to replace the default text editor component. Default value: undefined.

Example: Integrating a Rich Text Editor

import { Chat, MessageInput, useMessageInputState } from '@tencentcloud/chat-uikit-react';

// Custom rich text editor
function RichTextEditor() {
const { sendMessage } = useMessageInputState();
const [inputValue, setInputValue] = useState('');

const handleContentChange = (content: string) => {
setInputValue(content);
};

const handleKeyDown = (e: React.KeyboardEvent) => {
// Enter to send message
if (e.key === 'Enter') {
// Trigger sending logic
e.preventDefault();
sendMessage(inputValue);
// Clear input in editable div
const editableDiv = document.querySelector('.editable-div');
if (editableDiv) {
editableDiv.textContent = '';
}
}
};

return (
<div style={{
flex: 1,
border: '1px solid #d9d9d9',
borderRadius: '6px',
padding: '8px 12px',
minHeight: '32px',
maxHeight: '120px',
overflow: 'auto',
}}
>
<div
contentEditable
className="editable-div"
style={{
outline: 'none',
minHeight: '20px',
lineHeight: '20px',
}}
onInput={(e) => {
handleContentChange(e.currentTarget.textContent || '');
}}
onKeyDown={handleKeyDown}
/>
</div>
);
}

function ChatWithRichTextEditor() {
return (
<Chat>
<MessageInput TextEditor={<RichTextEditor />} />
</Chat>
);
}
The rendering is shown in the figure below:


EmojiPicker

type: JSX.Element
EmojiPicker replaces the default emoji selector component, default value undefined.

Example: Custom Emoji Panel

import { Chat, MessageInput, useMessageInputState } from '@tencentcloud/chat-uikit-react';

// Custom Emoji Selector
function CustomEmojiPicker() {
const { insertContent } = useMessageInputState();

const emojiCategories = {
common: ['😀', '😂', '🥰', '😍', '🤔', '😭', '😡', '👍'],
hands: ['👋', '🤝', '👏', '🙏', '✌️', '🤞', '🤟', '👌'],
animals: ['🐶', '🐱', '🐭', '🐹', '🐰', '🦊', '🐻', '🐼'],
};

const [activeCategory, setActiveCategory] = useState('common');
const [showPicker, setShowPicker] = useState(false);

const insertEmoji = (emoji: string) => {
insertContent(emoji);
setShowPicker(false);
};

return (
<div style={{ position: 'relative' }}>
<button
onClick={() => setShowPicker(!showPicker)}
style={{ border: 'none', background: 'transparent', cursor: 'pointer' }}
>
😊
</button>

{showPicker && (
<div style={{
position: 'absolute',
bottom: '100%',
left: 0,
background: 'white',
border: '1px solid #ccc',
borderRadius: '8px',
padding: '12px',
width: '280px',
boxShadow: '0 4px 12px rgba(0,0,0,0.1)',
}}
>
{/* Category tag */}
<div style={{ display: 'flex', marginBottom: '8px' }}>
{Object.keys(emojiCategories).map(category => (
<button
key={category}
onClick={() => setActiveCategory(category)}
style={{
padding: '4px 8px',
border: 'none',
background: activeCategory === category ? '#1890ff' : 'transparent',
color: activeCategory === category ? 'white' : '#666',
borderRadius: '4px',
cursor: 'pointer',
fontSize: '12px',
}}
>
{category}
</button>
))}
</div>

{/* Emoji grid */}
<div style={{
display: 'grid',
gridTemplateColumns: 'repeat(8, 1fr)',
gap: '4px',
}}
>
{emojiCategories[activeCategory].map(emoji => (
<button
key={emoji}
onClick={() => insertEmoji(emoji)}
style={{
border: 'none',
background: 'transparent',
fontSize: '20px',
cursor: 'pointer',
padding: '4px',
borderRadius: '4px',
}}
>
{emoji}
</button>
))}
</div>
</div>
)}
</div>
);
}

function ChatWithCustomEmoji() {
return (
<Chat>
<MessageInput EmojiPicker={<CustomEmojiPicker />} />
</Chat>
);
}
The rendering is shown in the figure below:


AttachmentPicker

type: JSX.Element
AttachmentPicker is used to replace the default attachment selector component, default value is undefined.

Example: Attachment Selector for Storage Integration

import { Chat, MessageInput } from '@tencentcloud/chat-uikit-react';

// Attachment Selector with Cloud Storage Integration
function CloudAttachmentPicker() {
const [showPicker, setShowPicker] = useState(false);
const attachmentTypes = [
{ key: 'local', label: 'local file', icon: '📁' },
{ key: 'cloud', label: 'cloud file', icon: '☁️' },
{ key: 'recent', label: 'recent file', icon: '🕒' },
{ key: 'screenshot', label: 'screenshot', icon: '📷' }
];

const handleAttachmentSelect = async (type: string) => {
switch (type) {
case 'local':
// Open local file selection
const input = document.createElement('input');
input.type = 'file';
input.multiple = true;
input.onchange = (e) => {
const files = (e.target as HTMLInputElement).files;
console.log('selected local files:', files);
};
input.click();
break;
case 'cloud':
// Toggle on cloud file selection
console.log('Toggle on cloud file selection');
break;
case 'recent':
// Display recent files
console.log('Display recent files');
break;
case 'screenshot':
// Start screenshot
console.log('start screenshot')
break;
}
setShowPicker(false);
};

return (
<div style={{ position: 'relative' }}>
<button
onClick={() => setShowPicker(!showPicker)}
style={{ border: 'none', background: 'transparent', cursor: 'pointer' }}
>
📎
</button>
{showPicker && (
<div style={{
position: 'absolute',
bottom: '100%',
left: 0,
background: 'white',
border: '1px solid #ccc',
borderRadius: '8px',
padding: '8px',
minWidth: '160px',
boxShadow: '0 4px 12px rgba(0,0,0,0.1)'
}}>
{attachmentTypes.map(type => (
<div
key={type.key}
onClick={() => handleAttachmentSelect(type.key)}
style={{
display: 'flex',
alignItems: 'center',
gap: '8px',
padding: '8px 12px',
cursor: 'pointer',
borderRadius: '4px',
fontSize: '14px'
}}
>
<span>{type.icon}</span>
<span>{type.label}</span>
</div>
))}
</div>
)}
</div>
);
}

function ChatWithCloudAttachment() {
return (
<Chat>
<MessageInput AttachmentPicker={<CloudAttachmentPicker />} />
</Chat>
);
}
The rendering is shown in the figure below:


Summary

The MessageInput component provides complete message input functionality and various custom options. By reasonably configuring Props and using the slot system, you can create an input interface that meets specific business requirements. It is recommended to choose an appropriate customized scheme based on real-world usage scenarios and maintain good user experience and performance.

Help and Support

Was this page helpful?

Help us improve! Rate your documentation experience in 5 mins.

Feedback