'use client'; import { Button } from '../ui/button'; import { cn } from '../../src/lib/utils'; import { ArrowDownIcon, UserIcon } from 'lucide-react'; import type { ComponentProps } from 'react'; import { useCallback } from 'react'; import { StickToBottom, useStickToBottomContext } from 'use-stick-to-bottom'; export type ConversationProps = ComponentProps; export const Conversation = ({ className, ...props }: ConversationProps) => ( ); export type ConversationContentProps = ComponentProps; export const ConversationContent = ({ className, ...props }: ConversationContentProps) => ( ); export type ConversationEmptyStateProps = ComponentProps<'div'> & { title?: string; description?: string; icon?: React.ReactNode; }; export const ConversationEmptyState = ({ className, title = 'No messages yet', description = 'Start a conversation to see messages here', icon, children, ...props }: ConversationEmptyStateProps) => (
{children ?? ( <> {icon &&
{icon}
}

{title}

{description &&

{description}

}
)}
); export type ConversationScrollButtonProps = ComponentProps; /** * Button to scroll to the bottom of the conversation. * Can be used standalone or within ConversationScrollButtons container. * When used standalone, it handles its own visibility based on isAtBottom. * When used in ConversationScrollButtons, the container manages visibility. */ export const ConversationScrollButton = ({ className, ...props }: ConversationScrollButtonProps) => { const { scrollToBottom } = useStickToBottomContext(); const handleScrollToBottom = useCallback(() => { scrollToBottom(); }, [scrollToBottom]); return ( ); }; /** * Data attribute used to mark the last user message element. * ChatInterface adds this attribute to the last user message for scroll targeting. */ export const LAST_USER_MESSAGE_ATTR = 'data-last-user-message'; export type ConversationScrollToLastUserMessageButtonProps = ComponentProps; /** * Button to scroll to the last user message in the conversation. * Reference: Issue #3 - Provide a feature to locate the last human message */ export const ConversationScrollToLastUserMessageButton = ({ className, ...props }: ConversationScrollToLastUserMessageButtonProps) => { const handleScrollToLastUserMessage = useCallback(() => { // Find the last user message element by data attribute const lastUserMessage = document.querySelector(`[${LAST_USER_MESSAGE_ATTR}="true"]`); if (lastUserMessage) { lastUserMessage.scrollIntoView({ behavior: 'smooth', block: 'start' }); } }, []); return ( ); }; export type ConversationScrollButtonsProps = ComponentProps<'div'> & { /** Whether there are user messages to scroll to */ hasUserMessages?: boolean; }; /** * Container for scroll navigation buttons. * Renders scroll-to-last-user-message and scroll-to-bottom buttons side by side. * Reference: Issue #3 - Provide a feature to locate the last human message */ export const ConversationScrollButtons = ({ className, hasUserMessages = false, ...props }: ConversationScrollButtonsProps) => { const { isAtBottom } = useStickToBottomContext(); if (isAtBottom) return null; return (
{hasUserMessages && }
); };