About
A user message with copy and edit actions, inline editing with keyboard shortcuts, and switching between edited versions.
Built with React and Tailwind. Copy the prompt and paste it into Claude Code, Cursor or Lovable: your agent adds Edit Message to your project and fits it to your theme.
Code
How Edit Message is used: the demo's code. The component's own source comes with a free account.
Usage.tsx
import * as React from 'react'
import { EditMessage } from '@/components/ui/edit-message'
const original = 'Focus the next collection on conversation recovery.'
const revised = 'Focus the next collection on conversation recovery and keyboard navigation.'
const extra = revised.slice(original.length - 1)
type Phase = 'idle' | 'editing' | 'saved'
export default function Demo() {
const [phase, setPhase] = React.useState<Phase>('editing')
const [typed, setTyped] = React.useState(12)
const [versions, setVersions] = React.useState([original])
const [active, setActive] = React.useState(0)
const [draft, setDraft] = React.useState(original.slice(0, -1) + extra.slice(0, 12))
const [auto, setAuto] = React.useState(true)
React.useEffect(() => {
if (!auto) return
if (phase === 'editing' && typed < extra.length) {
const timer = setTimeout(() => {
setTyped((value) => value + 1)
setDraft(original.slice(0, -1) + extra.slice(0, typed + 1))
}, 45)
return () => clearTimeout(timer)
}
const timer = setTimeout(
() => {
if (phase === 'idle') {
setDraft(original)
setTyped(0)
setPhase('editing')
} else if (phase === 'editing') {
setVersions([original, revised])
setActive(1)
setPhase('saved')
} else {
setVersions([original])
setActive(0)
setPhase('idle')
}
},
phase === 'saved' ? 3600 : phase === 'idle' ? 1600 : 700,
)
return () => clearTimeout(timer)
}, [auto, phase, typed])
return (
<div className="w-full max-w-lg" onPointerDown={() => setAuto(false)}>
<EditMessage
activeVersion={active}
draft={draft}
editing={phase === 'editing'}
onActiveVersionChange={setActive}
onDraftChange={setDraft}
onEditingChange={(editing) => setPhase(editing ? 'editing' : 'saved')}
onSave={(value) => setVersions((current) => [...current, value])}
versions={versions}
/>
</div>
)
}








