Edit Message
An in-place message editor with cancel and save actions.
Usage
import { EditMessage } from "@/components/ai/edit-message"
export function Example() {
return <EditMessage value={value} onValueChange={setValue} />
}
Install
pnpm dlx shadcn@latest add @pastaui/edit-messagenpx shadcn@latest add @pastaui/edit-messageyarn dlx shadcn@latest add @pastaui/edit-messagebunx --bun shadcn@latest add @pastaui/edit-messageSource
import { CheckCircleIcon as CheckIcon } from '@solar-icons/react/linear/check-circle'
import { CloseIcon as XIcon } from '@solar-icons/react/linear/close'
import * as React from 'react'
import { Button } from '@/components/ui/button'
import { Textarea } from '@/components/ui/textarea'
import { cn } from 'cn'
interface EditMessageProps extends React.ComponentProps<'section'> {
onCancel?: () => void
onSave?: () => void
onValueChange?: (value: string) => void
value: string
}
function EditMessage({
className,
onCancel,
onSave,
onValueChange,
value,
...props
}: EditMessageProps) {
return (
<section
data-slot="edit-message"
className={cn(
'rounded-[16px] border-0 bg-muted/45 p-3 shadow-none ring-0 transition-[opacity,scale] duration-200 ease-[cubic-bezier(0.23,1,0.32,1)] starting:scale-[0.98] starting:opacity-0 motion-reduce:starting:scale-100',
className,
)}
{...props}
>
<label className="sr-only" htmlFor="edit-message-value">
Edit message
</label>
<Textarea
id="edit-message-value"
placeholder="Edit your message…"
className="min-h-20 resize-none border-0 bg-transparent px-2 py-2 text-sm shadow-none ring-0 focus-visible:ring-0 dark:bg-transparent"
onChange={(event) => onValueChange?.(event.target.value)}
value={value}
/>
<div className="mt-2 flex items-center justify-end gap-1.5 tracking-[-0.05px]">
{onCancel && (
<Button
className="h-7 rounded-full px-3 text-muted-foreground hover:text-muted-foreground has-data-[icon=inline-start]:pl-3"
onClick={onCancel}
size="sm"
variant="ghost"
>
<XIcon data-icon="inline-start" /> Cancel
</Button>
)}
{onSave && (
<Button
className="h-7 rounded-full border-0 bg-primary bg-linear-to-b from-[color-mix(in_oklch,var(--primary),var(--primary-foreground)_30%)] to-primary px-3 text-primary-foreground shadow-[inset_0_1px_0_rgba(255,255,255,0.14),0_1px_2px_rgba(0,0,0,0.18)] shadow-none hover:brightness-110 has-data-[icon=inline-start]:pl-3 dark:bg-none"
onClick={onSave}
size="sm"
variant="default"
>
<CheckIcon data-icon="inline-start" /> Save and send
</Button>
)}
</div>
</section>
)
}
export { EditMessage }
export type { EditMessageProps }
Props
| Prop | Type | Default | Description |
|---|---|---|---|
| value | string | = — | Controls the edited message. |
| onSave | () => void | = — | Saves and resends the edited message. |