Skip to content
ConversationMessage editMenu

Message edit

Inline editing of a user message. It grows with the text, warns how many replies saving will replace, and never saves in the middle of IME composition.

Editing warns how many replies it replaces.

Installation

$ pnpm dlx shadcn@latest add https://chatcn.dev/r/message-edit.json

Usage

tsx
import { MessageEdit } from "@/components/ui/chatcn/message-edit"

<Message from="user">
  {editing ? (
    <MessageEdit
      defaultValue={text}
      replies={repliesAfter(message.id)}
      onSave={(next) => editMessage(message.id, next)}
      onCancel={() => setEditing(false)}
    />
  ) : (
    <MessageContent>{text}</MessageContent>
  )}
</Message>

Props

PropTypeNotes
defaultValuestringThe text to start from
onSave(text) => voidTrimmed text. Saving unchanged text cancels
onCancel() => void
repliesnumberReplies that saving replaces. Shows the warning above 0
maxHeightnumberGrow limit in px. Defaults to 40% of the viewport

Keyboard

KeyAction
EnterSave, unless an IME is composing
Shift EnterNew line
EscCancel

Accessibility

  • The field is focused on open with the caret at the end.
  • The replaces-replies warning is linked to the field with aria-describedby.
  • Enter checks isComposing and key code 229, so Japanese, Chinese and Korean input work in every browser.

Motion

None. The field resizes directly as you type; an animated height would lag behind the caret.