div]:pb-0', className)} {...props} />
);
};
export type MessageBranchContentProps = HTMLAttributes
;
export const MessageBranchContent = ({ children, ...props }: MessageBranchContentProps) => {
const { currentBranch, setBranches, branches } = useMessageBranch();
const childrenArray = Array.isArray(children) ? children : [children];
// Use useEffect to update branches when they change
useEffect(() => {
if (branches.length !== childrenArray.length) {
setBranches(childrenArray);
}
}, [childrenArray, branches, setBranches]);
return childrenArray.map((branch, index) => (
div]:pb-0',
index === currentBranch ? 'block' : 'hidden'
)}
key={branch.key}
{...props}
>
{branch}
));
};
export type MessageBranchSelectorProps = HTMLAttributes & {
from: UIMessage['role'];
};
export const MessageBranchSelector = ({
className,
from,
...props
}: MessageBranchSelectorProps) => {
const { totalBranches } = useMessageBranch();
// Don't render if there's only one branch
if (totalBranches <= 1) {
return null;
}
return (
);
};
export type MessageBranchPreviousProps = ComponentProps;
export const MessageBranchPrevious = ({ children, ...props }: MessageBranchPreviousProps) => {
const { goToPrevious, totalBranches } = useMessageBranch();
return (
);
};
export type MessageBranchNextProps = ComponentProps;
export const MessageBranchNext = ({ children, className, ...props }: MessageBranchNextProps) => {
const { goToNext, totalBranches } = useMessageBranch();
return (
);
};
export type MessageBranchPageProps = HTMLAttributes;
export const MessageBranchPage = ({ className, ...props }: MessageBranchPageProps) => {
const { currentBranch, totalBranches } = useMessageBranch();
return (
{currentBranch + 1} of {totalBranches}
);
};
export type MessageResponseProps = ComponentProps;
export const MessageResponse = memo(
({ className, ...props }: MessageResponseProps) => (
*:first-child]:mt-0 [&>*:last-child]:mb-0', className)}
{...props}
/>
),
(prevProps, nextProps) => prevProps.children === nextProps.children
);
MessageResponse.displayName = 'MessageResponse';
export type MessageAttachmentProps = HTMLAttributes & {
data: FileUIPart;
className?: string;
onRemove?: () => void;
};
export function MessageAttachment({ data, className, onRemove, ...props }: MessageAttachmentProps) {
const filename = data.filename || '';
const mediaType = data.mediaType?.startsWith('image/') && data.url ? 'image' : 'file';
const isImage = mediaType === 'image';
const attachmentLabel = filename || (isImage ? 'Image' : 'Attachment');
return (
{isImage ? (
<>

{onRemove && (
)}
>
) : (
<>
{attachmentLabel}
{onRemove && (
)}
>
)}
);
}
export type MessageAttachmentsProps = ComponentProps<'div'>;
export function MessageAttachments({ children, className, ...props }: MessageAttachmentsProps) {
if (!children) {
return null;
}
return (
{children}
);
}
export type MessageToolbarProps = ComponentProps<'div'>;
export const MessageToolbar = ({ className, children, ...props }: MessageToolbarProps) => (
{children}
);