/* Copyright 2026 Marimo. All rights reserved. */ import type { FileUIPart } from "ai"; import { AtSignIcon, FileIcon, FileTextIcon, ImageIcon, PaperclipIcon, SendHorizontalIcon, StopCircleIcon, XIcon, } from "lucide-react"; import { useState } from "react"; import { cn } from "@/utils/cn"; import { Spinner } from "../icons/spinner"; import { Button } from "../ui/button"; import { Input } from "../ui/input"; import { Tooltip } from "../ui/tooltip"; import { SUPPORTED_ATTACHMENT_TYPES } from "./chat-utils"; export const AttachmentRenderer = ({ attachment, }: { attachment: FileUIPart; }) => { if (attachment.mediaType?.startsWith("image/")) { return ( {attachment.filename ); } return (
{attachment.filename || "Attachment"}
); }; export const FileAttachmentPill = ({ file, className, onRemove, }: { file: File; className?: string; onRemove: () => void; }) => { const [isHovered, setIsHovered] = useState(false); return (
setIsHovered(true)} onMouseLeave={() => setIsHovered(false)} > {isHovered ? ( ) : ( renderFileIcon(file) )} {file.name}
); }; export const SendButton = ({ isLoading, onStop, onSendClick, isEmpty, showStopLabel = false, // Show a stop label and spinner instead of just the stop icon when loading }: { isLoading: boolean; onStop: () => void; onSendClick: () => void; isEmpty: boolean; showStopLabel?: boolean; }) => { const loadingContent = showStopLabel ? (
Stop
) : ( ); return ( ); }; export const AddContextButton = ({ handleAddContext, isLoading, }: { handleAddContext: () => void; isLoading: boolean; }) => { return ( ); }; export const AttachFileButton = ({ fileInputRef, isLoading, onAddFiles, }: { fileInputRef: React.RefObject; isLoading: boolean; onAddFiles: (files: File[]) => void; }) => { return ( <> ) => { if (event.target.files) { onAddFiles([...event.target.files]); } }} accept={SUPPORTED_ATTACHMENT_TYPES.join(",")} /> ); }; function renderFileIcon(file: File): React.ReactNode { const classNames = "h-3 w-3 mt-0.5"; if (file.type.startsWith("image/")) { return ; } else if (file.type.startsWith("text/")) { return ; } return ; }