// Adapted from agentui (https://github.com/ashish200729/agentui), components/agents/message-bubble.tsx // Copyright (c) 2026 Saurabh Chauhan. MIT License, see ./LICENSE-agentui.md // 改造:去掉 motion 的 layout 动画与 render 克隆;变体底色换语义 token(soft = foreground 洗层,danger = destructive, // warning 为新增);折叠遮罩用 mask-image 渐变到 transparent(不写十六进制),箭头旋转用 duration-base。 import { ChevronDown } from "lucide-react"; import { type ComponentPropsWithRef, createContext, useContext, useId, useState } from "react"; import { cn } from "~/lib/utils.ts"; import { CHEVRON_CLASS } from "./disclosure.tsx"; import { MessageSideContext } from "./message.tsx"; export type MessageBubbleVariant = "solid" | "soft" | "outline" | "ghost" | "danger" | "warning"; const BubbleContext = createContext<{ variant: MessageBubbleVariant; align: "start" | "end" }>({ variant: "soft", align: "start", }); export function MessageBubble({ variant = "soft", align, className, ...props }: ComponentPropsWithRef<"div"> & { variant?: MessageBubbleVariant; align?: "start" | "end" }) { const side = useContext(MessageSideContext); const resolved = align ?? side ?? "start"; return (
); } const VARIANT: Record = { solid: "bg-foreground text-background", soft: "border border-border/60 bg-foreground/[0.05]", outline: "border border-border/70", ghost: "w-full max-w-none rounded-none border-0 px-0 py-0", danger: "border border-destructive/40 bg-destructive/10 text-destructive", warning: "border border-warning/40 bg-warning/10 text-warning", }; export function MessageBubbleContent({ className, ...props }: ComponentPropsWithRef<"div">) { const { variant } = useContext(BubbleContext); return (
); } const CLAMP = { 2: "line-clamp-2", 3: "line-clamp-3", 4: "line-clamp-4", 5: "line-clamp-5", 6: "line-clamp-6", } as const; /** 长消息折叠:收起时按行截断并渐隐 */ export function MessageBubbleCollapsible({ collapsedLines = 4, moreLabel = "展开", lessLabel = "收起", className, children, ...props }: ComponentPropsWithRef<"div"> & { collapsedLines?: 2 | 3 | 4 | 5 | 6; moreLabel?: string; lessLabel?: string }) { const id = useId(); const [open, setOpen] = useState(false); return (
{children}
); }