Getting Started
Components
- Accordion
- Advanced Toast
- AlertMessage
- ArrowButton
- Arrows
- Avatar
- Backdrop
- Basic Toast
- Breadcrumb
- Button
- CardBackground
- Card
- Carousel
- Chapters
- ChatBody
- ChatButton
- ChatHeader
- ChatInput
- ChatMessageActions
- ChatMessageEditor
- ChatMessage
- ChatTypingIndicator
- ChatWindowCsatPrompt
- ChatWindowQuote
- ChatWindow
- CheckboxSelect
- Checkbox
- Checkboxes
- Chip
- ChoiceExpander
- Clickable
- ContentReview
- Countdown
- CriteriaDates
- CriteriaParticipants
- CriteriaTransports
- Date Field
- Datepicker
- Dropdown
- ElasticHeight
- ExpandableCard
- ExpandableText
- Filter
- FloatingLabelTextField
- Form Control
- Form Label
- Frame
- HamburgerIcon
- Heading
- Image
- JourneyCard
- LayerHeader
- Layer
- Link
- Loader
- Number Field
- PageNavigation
- Pagination
- Paragraph
- Password
- Phone Field
- Popin
- Portal
- ProductThumbnail
- Promises
- Prose
- Radio Group
- RadioSelect
- Radio
- Range
- Scrollbar
- Select
- SidebarLayout
- SliderFrame
- SparkleWrapper
- Spinner
- Switch
- Table
- Tabs
- Tag
- TextField
- Toggle
- Tooltip
- ValidationMessage
'use client';
import { useState } from 'react';
import { ChatMessageEditor } from '@/ui/chat/ChatMessageEditor';
export function ChatMessageEditorDemo() {
const [message, setMessage] = useState('My son is 14 years old, what activities do you suggest?');
const [isEditing, setIsEditing] = useState(true);
return (
<div className="w-[380px] flex flex-col items-end gap-8 px-20">
{isEditing ? (
<ChatMessageEditor
value={message}
onCancel={() => setIsEditing(false)}
onSubmit={(content) => {
setMessage(content);
setIsEditing(false);
}}
/>
) : (
<>
<p className="text-b3 bg-lightSand rounded-32 px-24 py-12 text-black">{message}</p>
<button
type="button"
onClick={() => setIsEditing(true)}
className="text-b4 font-semibold underline underline-offset-2"
>
Edit again
</button>
</>
)}
</div>
);
}
Installation
npx shadcn@latest add https://develop.trident-ui.pro.clubmed/r/chat-message-editor.json
Usage
ChatMessageEditor replaces the bubble of a user message while it is edited.
ChatMessage already does it for you when you give it
onEdit: use this component to build your own message bubble.
import { ChatMessageEditor } from '@/ui/chat/ChatMessageEditor';
import { useState } from 'react';
export function Component() {
const [message, setMessage] = useState('My son is 14 years old.');
const [isEditing, setIsEditing] = useState(true);
return isEditing ? (
<ChatMessageEditor
value={message}
onCancel={() => setIsEditing(false)}
onSubmit={(content) => {
setMessage(content);
setIsEditing(false);
}}
/>
) : (
<p>{message}</p>
);
}Behavior
- The textarea is focused on mount, with the caret at the end, and grows with its content.
- Send is disabled while the text is empty or identical to
value(ignoring the surrounding spaces), andonSubmitreceives the trimmed text. - Esc cancels, Ctrl/Cmd + Enter sends. A plain Enter adds a line break.
- Cancelling throws the draft away: the next edition starts again from
value.
Translate the labels
<ChatMessageEditor
value="Bonjour"
labels={{ cancel: 'Annuler', send: 'Envoyer' }}
onCancel={() => {}}
onSubmit={() => {}}
/>API Reference
ChatMessageEditor
| Prop | Type | Default | Description |
|---|---|---|---|
value | string | — | Required. Initial text of the editor |
onSubmit | (value: string) => void | — | Required. Called with the trimmed text when it is sent |
onCancel | () => void | — | Required. Called when the edition is cancelled |
labels | Partial<ChatMessageLabels> | English | Only cancel ("Cancel") and send ("Send") are used |
See ChatMessageActions for the
ChatMessageLabels type.
Notes
- Only text can be edited: rich content (for instance rendered Markdown) cannot be put in a textarea.
- The textarea is labelled "Edit message".