Component
MessageActions
Thanh thao tác tin nhắn hiện khi hover, focus hoặc chạm: bày tỏ cảm xúc, trả lời, chuyển tiếp, ghim và chọn, rồi tới các control của bạn như menu Thêm. Nút cảm xúc mở cảm xúc nhanh và EmojiPicker đầy đủ. Truyền nó cho MessageBubble làm toolbar.
Xem trước
import { MessageActions } from "@/components/ui/message-actions"
const addReaction = (emoji: string) => { /* Thêm cảm xúc của người đọc vào tin nhắn. */ }
const replyToMessage = () => { /* Đưa tin nhắn vào replyTo của Composer. */ }
const forwardMessage = () => { /* Mở hộp thoại chuyển tiếp. */ }
const setPinned = (pinned: boolean) => { /* Ghim hoặc bỏ ghim tin nhắn. */ }
const startSelection = () => { /* Bật chế độ chọn với tin nhắn này được chọn. */ }
const messageActionsLabelsVi = { toolbar: "Thao tác tin nhắn", react: "Bày tỏ cảm xúc", reply: "Trả lời", forward: "Chuyển tiếp", pin: "Ghim", select: "Chọn", moreReactions: "Thêm cảm xúc", quickReactions: "Cảm xúc nhanh" }
<MessageActions onReact={addReaction} onReply={replyToMessage} onForward={forwardMessage} onPinnedChange={setPinned} onSelect={startSelection} labels={messageActionsLabelsVi} />Cách dùng
Khi nào dùng
- Đưa ra các thao tác trên một tin (cảm xúc, trả lời, chuyển tiếp, ghim, chọn) khi người đọc trỏ vào, focus hoặc chạm vào nó.
- Thêm menu Thêm với các thao tác hiếm hơn, như Sao chép, Sửa và Xóa.
Khi nào không dùng
- Thao tác trên nhiều tin được chọn cùng lúc. Dùng chế độ chọn của MessageList với một thanh Button.
- Một thanh công cụ luôn hiện trên tài liệu. Dùng ToggleGroup hoặc một hàng Button.
- Menu chuột phải trên bất kỳ mục nào. Dùng ContextMenu.
Ví dụ
Thanh thao tác
import { MessageActions } from "@/components/ui/message-actions"
const addReaction = (emoji: string) => { /* Thêm cảm xúc của người đọc vào tin nhắn. */ }
const replyToMessage = () => { /* Đưa tin nhắn vào replyTo của Composer. */ }
const forwardMessage = () => { /* Mở hộp thoại chuyển tiếp. */ }
const setPinned = (pinned: boolean) => { /* Ghim hoặc bỏ ghim tin nhắn. */ }
const startSelection = () => { /* Bật chế độ chọn với tin nhắn này được chọn. */ }
<MessageActions onReact={addReaction} onReply={replyToMessage} onForward={forwardMessage} onPinnedChange={setPinned} onSelect={startSelection} />Tin đã ghim
Nút Ghim giữ trạng thái nhấn, với icon đặc, khi tin đang được ghim.
import { MessageActions } from "@/components/ui/message-actions"
const addReaction = (emoji: string) => { /* Thêm cảm xúc của người đọc vào tin nhắn. */ }
const replyToMessage = () => { /* Đưa tin nhắn vào replyTo của Composer. */ }
const setPinned = (pinned: boolean) => { /* Ghim hoặc bỏ ghim tin nhắn. */ }
<MessageActions pinned onReact={addReaction} onReply={replyToMessage} onPinnedChange={setPinned} />Có menu Thêm
Các control của bạn đứng sau các nút có sẵn.
import { IconCopy, IconDots, IconPencil, IconTrash } from "@tabler/icons-react"
import { Button } from "@/components/ui/button"
import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger } from "@/components/ui/dropdown-menu"
import { MessageActions } from "@/components/ui/message-actions"
const addReaction = (emoji: string) => { /* Thêm cảm xúc của người đọc vào tin nhắn. */ }
const replyToMessage = () => { /* Đưa tin nhắn vào replyTo của Composer. */ }
<MessageActions onReact={addReaction} onReply={replyToMessage}>
<DropdownMenu>
<DropdownMenuTrigger asChild>
<Button size="sm" variant="ghost" iconOnly aria-label="Thêm thao tác">
<IconDots size={16} />
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent align="end">
<DropdownMenuItem leadingIcon={<IconCopy size={16} />}>Copy text</DropdownMenuItem>
<DropdownMenuItem leadingIcon={<IconPencil size={16} />}>Edit</DropdownMenuItem>
<DropdownMenuItem destructive leadingIcon={<IconTrash size={16} />}>Delete</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
</MessageActions>Nên và không nên
Nên
- Chỉ truyền các handler cuộc trò chuyện hỗ trợ; mỗi handler hiện nút của nó.
- Đặt thao tác hiếm hoặc nguy hiểm (Sao chép, Sửa, Xóa) trong một DropdownMenu làm children.
- Giữ cảm xúc nhanh ở sáu hoặc ít hơn.
Không nên
- Đừng đặt nút chữ trong thanh; nó chỉ chứa nút icon.
- Đừng hiện thanh trên mọi tin cùng lúc; MessageBubble hiện nó khi hover, focus hoặc chạm.
- Đừng thêm hàng cảm xúc thứ hai dưới thanh; cảm xúc hiện trên tin nhắn.
Props
| Tên | Kiểu | Giá trị | Mặc định | Mô tả |
|---|---|---|---|---|
| onReact | (emoji: string) => void | - | - | Hiện nút cảm xúc, và được gọi với emoji được chọn. |
| quickReactions | string[] | - | - | Các cảm xúc đưa ra trước. Mặc định 👍 ❤️ 😂 😮 😢 🙏. |
| frequentEmoji | string[] | - | - | Emoji hiện đầu tiên trong bộ chọn đầy đủ. Mặc định: các cảm xúc nhanh. |
| onReply | () => void | - | - | Hiện nút Trả lời. Đưa tin vào replyTo của Composer. |
| onForward | () => void | - | - | Hiện nút Chuyển tiếp. |
| pinned | boolean | - | false | Tin có đang được ghim không. Nút Ghim ở trạng thái nhấn khi đang ghim. |
| onPinnedChange | (pinned: boolean) => void | - | - | Hiện nút Ghim, và được gọi với trạng thái ghim mới. |
| onSelect | () => void | - | - | Hiện nút Chọn. Bật chế độ chọn trong MessageList với tin này được chọn. |
| labels | { toolbar?: string; react?: string; reply?: string; forward?: string; pin?: string; select?: string; moreReactions?: string; quickReactions?: string; emojiPicker?: EmojiPickerLabels } | - | - | Tên của thanh và các nút. Mặc định: Message actions, React, Reply, Forward, Pin, Select, More reactions, Quick reactions. Tiếng Việt: Thao tác tin nhắn, Bày tỏ cảm xúc, Trả lời, Chuyển tiếp, Ghim, Chọn, Thêm cảm xúc, Cảm xúc nhanh. |
| children | node | - | - | Thêm control sau các nút có sẵn, như DropdownMenu với Sao chép, Sửa và Xóa. Dùng Button icon ghost cỡ sm. |
Cấu tạo
| Phần | Mô tả |
|---|---|
| root | Thanh thao tác: nền raised với viền ring và shadow-med, padding 4px. |
| action | Mỗi thao tác có sẵn: Button icon ghost cỡ sm kèm Tooltip. Cảm xúc, Trả lời, Chuyển tiếp, Ghim và Chọn, theo thứ tự đó. |
| popover | Popover mà nút cảm xúc mở phía trên thanh. |
| quick | Hàng cảm xúc nhanh với nút Thêm cảm xúc. |
| reaction | Một nút cảm xúc nhanh, cỡ của control md, chữ cỡ xl. |
| picker | EmojiPicker hiện sau khi nhấn Thêm cảm xúc. |
Khả năng truy cập
Role: toolbar
| Phím | Hành động |
|---|---|
| Tab | Chuyển vào thanh, tới nút có focus gần nhất. Thanh là một điểm dừng tab. |
| Arrow Left / Arrow Right | Chuyển tới nút trước hoặc sau, vòng lại ở hai đầu. Theo chiều phải sang trái. |
| Home / End | Chuyển tới nút đầu tiên hoặc cuối cùng. |
| Enter / Space | Chạy thao tác có focus. Trên nút cảm xúc, mở các cảm xúc. |
| Escape | Đóng các cảm xúc và đưa focus về nút cảm xúc. |
- Một toolbar được đặt tên bằng labels.toolbar (EN `Message actions`, VI `Thao tác tin nhắn`).
- Mỗi nút là nút icon được đặt tên bằng thao tác của nó và hiện cùng chữ đó trong Tooltip.
- Ghim là nút bật tắt: aria-pressed là true khi tin đang được ghim, và icon của nó chuyển sang dạng đặc.
- Các cảm xúc nhanh là nút được đặt tên bằng tên emoji, như EN `thumbs up`. Thêm cảm xúc mở EmojiPicker và focus vào ô tìm kiếm.
- Chỉ các thao tác có handler mới hiện, nên thanh không bao giờ đưa ra thứ không làm gì.
Cài đặt
npx werewolf-ui add message-actionsChạy npx werewolf-ui init một lần trong app trước khi thêm component. Init cài token, thêm CSS import và luật cho agent. Add cài component này cùng các dependency và giữ nguyên theme của bạn. Xem Cài đặt để biết yêu cầu và cách cài qua registry.