User message actions
ProThe row under the person's own message: Copy, and Edit, which hands the app the message's words to change and send again. Edit doesn't change the message: the app puts the words back in the composer (or its own editor), and what the person sends is a new message, with this one left in the thread, so the app keeps the versions and pages through them with MessageBranches, given as children. Each action appears only when its handler is given; nothing is chosen for the person.
It goes where Message draws the line under a person's own message, meta, beside the app's own name and time:
<Message message={m} meta={<UserMessageActions text={wordsOf(m)} onEdit={(text) => composer.edit(m.id, text)} />} />Version 5.2.0· other versions
This page is for 5.2.0, the current release. An earlier release’s page is the Markdown that release published, so the docs match the version you have installed (candor-lock.json records it).
Not in the docs of 1.3.0, 1.4.0, 1.5.0, 1.5.1, 1.6.0, 1.7.0, 1.8.0, 1.8.1, 1.9.0, 1.9.1, 2.0.0, 2.1.0, 2.2.0, 2.3.0, 2.4.0, 2.5.0, 2.5.1, 2.6.0, 2.6.1, 2.6.2, 2.7.0, 2.8.0, 2.9.0, 2.10.0, 3.0.0, 4.0.0, 4.0.1, 4.0.2, 4.1.0, 4.2.0, 4.3.0, 4.4.0, 4.5.0 and 5.0.0: the page came later, or had another name then.
Docs pages weren’t kept for 1.0.0, 1.0.1, 1.1.0, 1.1.1, 1.2.0 and 1.2.1: they are kept from 1.3.0 on, and before that only llms.txt was published.
Preview
Loading the preview
Install
First time? Get started sets up the registry and theme. Or with shadcn directly: npx shadcn@latest add @candor/user-message-actions
Brings in: locale, message-actions, tokens, tooltip, utils · npm: lucide-react@^1.67.0
Usage
"use client"
import * as React from "react"
import { Message } from "@/components/candor/message"
import { MessageBranches } from "@/components/candor/message-branches"
import { UserMessageActions } from "@/components/candor/user-message-actions"
/*
* The app keeps the versions: Edit hands back the words (here they'd go to the composer), and what the person sends
* is a new message. MessageBranches pages through the versions the app kept.
*/
const versions = ["Draft the launch note", "Draft the launch note for the EU team"]
export default function Example() {
const [index, setIndex] = React.useState(versions.length - 1)
const [editing, setEditing] = React.useState<string | null>(null)
const text = versions[index]!
return (
<div className="flex max-w-md flex-col gap-2 text-sm">
<Message
message={{ id: "m1", author: { role: "user" }, status: "complete", blocks: [{ kind: "plain", text }] }}
meta={
<UserMessageActions text={text} onEdit={setEditing}>
<MessageBranches index={index} count={versions.length} onValueChange={setIndex} />
</UserMessageActions>
}
/>
<p className="text-xs text-muted-foreground">{editing === null ? "Choose Edit to put the words back in the composer." : `In the composer: “${editing}”`}</p>
</div>
)
}<UserMessageActions>
| Prop | Type | Default | Description |
|---|---|---|---|
| text | string | undefined | — | The message's words: what Copy copies, and what Edit hands back. Without it there's no Copy. |
| onEdit | ((text: string) => void) | undefined | — | Shows Edit, with `text`: called with it when the person chooses Edit, to put in the composer for a new message. |
| children | React.ReactNode | undefined | — | After the actions, e.g. `MessageBranches` for the versions the app keeps, or its own name and time. |
| className | string | undefined | — | Classes for the row, merged with Candor's. |
Strings
The fixed words, in English by default. Change any of them under userMessageActions in <LocaleProvider strings={{ … }}>; the table is exported as userMessageActionsStrings.
| Key | English |
|---|---|
| edit | Edit and send again |
| editHint | Sends your edited words as a new message. This one stays as it is. |
Motion
| Moment | Family | What it does |
|---|---|---|
| tint | tint | Each button's background and text change when the pointer is over it. |
Set with --cd-motion-user-message-actions-<moment>-* in your brand file; the families are in the design reference.