1 line
22 KiB
Plaintext
1 line
22 KiB
Plaintext
{"version":3,"file":"CopilotChatView.cjs","names":["useKeyboardHeight","renderSlot","CopilotChatMessageView","CopilotChatInput","CopilotChatSuggestionView","StickToBottom","cn","Button","ChevronDown","useCopilotChatConfiguration","CopilotChatDefaultLabels"],"sources":["../../../src/components/chat/CopilotChatView.tsx"],"sourcesContent":["import React, { useRef, useState, useEffect } from \"react\";\nimport { WithSlots, SlotValue, renderSlot } from \"@/lib/slots\";\nimport CopilotChatMessageView from \"./CopilotChatMessageView\";\nimport CopilotChatInput, {\n CopilotChatInputProps,\n CopilotChatInputMode,\n} from \"./CopilotChatInput\";\nimport CopilotChatSuggestionView, {\n CopilotChatSuggestionViewProps,\n} from \"./CopilotChatSuggestionView\";\nimport { Suggestion } from \"@copilotkitnext/core\";\nimport { Message } from \"@ag-ui/core\";\nimport { twMerge } from \"tailwind-merge\";\nimport {\n StickToBottom,\n useStickToBottom,\n useStickToBottomContext,\n} from \"use-stick-to-bottom\";\nimport { ChevronDown } from \"lucide-react\";\nimport { Button } from \"@/components/ui/button\";\nimport { cn } from \"@/lib/utils\";\nimport {\n useCopilotChatConfiguration,\n CopilotChatDefaultLabels,\n} from \"@/providers/CopilotChatConfigurationProvider\";\nimport { useKeyboardHeight } from \"@/hooks/use-keyboard-height\";\n\n// Height of the feather gradient overlay (h-24 = 6rem = 96px)\nconst FEATHER_HEIGHT = 96;\n\n// Forward declaration for WelcomeScreen component type\nexport type WelcomeScreenProps = WithSlots<\n {\n welcomeMessage: React.FC<React.HTMLAttributes<HTMLDivElement>>;\n },\n {\n input: React.ReactElement;\n suggestionView: React.ReactElement;\n } & React.HTMLAttributes<HTMLDivElement>\n>;\n\nexport type CopilotChatViewProps = WithSlots<\n {\n messageView: typeof CopilotChatMessageView;\n scrollView: typeof CopilotChatView.ScrollView;\n input: typeof CopilotChatInput;\n suggestionView: typeof CopilotChatSuggestionView;\n },\n {\n messages?: Message[];\n autoScroll?: boolean;\n isRunning?: boolean;\n suggestions?: Suggestion[];\n suggestionLoadingIndexes?: ReadonlyArray<number>;\n onSelectSuggestion?: (suggestion: Suggestion, index: number) => void;\n welcomeScreen?: SlotValue<React.FC<WelcomeScreenProps>> | boolean;\n // Input behavior props\n onSubmitMessage?: (value: string) => void;\n onStop?: () => void;\n inputMode?: CopilotChatInputMode;\n inputValue?: string;\n onInputChange?: (value: string) => void;\n onStartTranscribe?: () => void;\n onCancelTranscribe?: () => void;\n onFinishTranscribe?: () => void;\n onFinishTranscribeWithAudio?: (audioBlob: Blob) => Promise<void>;\n /**\n * @deprecated Use the `input` slot's `disclaimer` prop instead:\n * ```tsx\n * <CopilotChat input={{ disclaimer: MyDisclaimer }} />\n * ```\n */\n disclaimer?: SlotValue<React.FC<React.HTMLAttributes<HTMLDivElement>>>;\n } & React.HTMLAttributes<HTMLDivElement>\n>;\n\nexport function CopilotChatView({\n messageView,\n input,\n scrollView,\n suggestionView,\n welcomeScreen,\n messages = [],\n autoScroll = true,\n isRunning = false,\n suggestions,\n suggestionLoadingIndexes,\n onSelectSuggestion,\n // Input behavior props\n onSubmitMessage,\n onStop,\n inputMode,\n inputValue,\n onInputChange,\n onStartTranscribe,\n onCancelTranscribe,\n onFinishTranscribe,\n onFinishTranscribeWithAudio,\n // Deprecated — forwarded to input slot\n disclaimer,\n children,\n className,\n ...props\n}: CopilotChatViewProps) {\n const inputContainerRef = useRef<HTMLDivElement>(null);\n const [inputContainerHeight, setInputContainerHeight] = useState(0);\n const [isResizing, setIsResizing] = useState(false);\n const resizeTimeoutRef = useRef<NodeJS.Timeout | null>(null);\n\n // Track keyboard state for mobile\n const { isKeyboardOpen, keyboardHeight, availableHeight } =\n useKeyboardHeight();\n\n // Track input container height changes\n useEffect(() => {\n const element = inputContainerRef.current;\n if (!element) return;\n\n const resizeObserver = new ResizeObserver((entries) => {\n for (const entry of entries) {\n const newHeight = entry.contentRect.height;\n\n // Update height and set resizing state\n setInputContainerHeight((prevHeight) => {\n if (newHeight !== prevHeight) {\n setIsResizing(true);\n\n // Clear existing timeout\n if (resizeTimeoutRef.current) {\n clearTimeout(resizeTimeoutRef.current);\n }\n\n // Set isResizing to false after a short delay\n resizeTimeoutRef.current = setTimeout(() => {\n setIsResizing(false);\n }, 250);\n\n return newHeight;\n }\n return prevHeight;\n });\n }\n });\n\n resizeObserver.observe(element);\n\n // Set initial height\n setInputContainerHeight(element.offsetHeight);\n\n return () => {\n resizeObserver.disconnect();\n if (resizeTimeoutRef.current) {\n clearTimeout(resizeTimeoutRef.current);\n }\n };\n }, []);\n\n const BoundMessageView = renderSlot(messageView, CopilotChatMessageView, {\n messages,\n isRunning,\n });\n\n const BoundInput = renderSlot(input, CopilotChatInput, {\n onSubmitMessage,\n onStop,\n mode: inputMode,\n value: inputValue,\n onChange: onInputChange,\n isRunning,\n onStartTranscribe,\n onCancelTranscribe,\n onFinishTranscribe,\n onFinishTranscribeWithAudio,\n positioning: \"absolute\",\n keyboardHeight: isKeyboardOpen ? keyboardHeight : 0,\n containerRef: inputContainerRef,\n showDisclaimer: true,\n ...(disclaimer !== undefined ? { disclaimer } : {}),\n } as CopilotChatInputProps);\n\n const hasSuggestions = Array.isArray(suggestions) && suggestions.length > 0;\n const BoundSuggestionView = hasSuggestions\n ? renderSlot(suggestionView, CopilotChatSuggestionView, {\n suggestions,\n loadingIndexes: suggestionLoadingIndexes,\n onSelectSuggestion,\n className: \"cpk:mb-3 cpk:lg:ml-4 cpk:lg:mr-4 cpk:ml-0 cpk:mr-0\",\n })\n : null;\n\n const BoundScrollView = renderSlot(scrollView, CopilotChatView.ScrollView, {\n autoScroll,\n inputContainerHeight,\n isResizing,\n children: (\n <div\n style={{\n paddingBottom: `${inputContainerHeight + FEATHER_HEIGHT + (hasSuggestions ? 4 : 32)}px`,\n }}\n >\n <div className=\"cpk:max-w-3xl cpk:mx-auto\">\n {BoundMessageView}\n {hasSuggestions ? (\n <div className=\"cpk:pl-0 cpk:pr-4 cpk:sm:px-0 cpk:mt-4\">\n {BoundSuggestionView}\n </div>\n ) : null}\n </div>\n </div>\n ),\n });\n\n // Welcome screen logic\n const isEmpty = messages.length === 0;\n // Type assertion needed because TypeScript doesn't fully propagate `| boolean` through WithSlots\n const welcomeScreenDisabled = (welcomeScreen as unknown) === false;\n const shouldShowWelcomeScreen = isEmpty && !welcomeScreenDisabled;\n\n if (shouldShowWelcomeScreen) {\n // Create a separate input for welcome screen with static positioning and disclaimer visible\n const BoundInputForWelcome = renderSlot(input, CopilotChatInput, {\n onSubmitMessage,\n onStop,\n mode: inputMode,\n value: inputValue,\n onChange: onInputChange,\n isRunning,\n onStartTranscribe,\n onCancelTranscribe,\n onFinishTranscribe,\n onFinishTranscribeWithAudio,\n positioning: \"static\",\n showDisclaimer: true,\n ...(disclaimer !== undefined ? { disclaimer } : {}),\n } as CopilotChatInputProps);\n\n // Convert boolean `true` to undefined (use default), and exclude `false` since we've checked for it\n const welcomeScreenSlot = (\n welcomeScreen === true ? undefined : welcomeScreen\n ) as SlotValue<React.FC<WelcomeScreenProps>> | undefined;\n const BoundWelcomeScreen = renderSlot(\n welcomeScreenSlot,\n CopilotChatView.WelcomeScreen,\n {\n input: BoundInputForWelcome,\n suggestionView: BoundSuggestionView ?? <></>,\n },\n );\n\n return (\n <div\n data-copilotkit\n data-testid=\"copilot-chat\"\n data-copilot-running={isRunning ? \"true\" : \"false\"}\n className={twMerge(\n \"copilotKitChat cpk:relative cpk:h-full cpk:flex cpk:flex-col\",\n className,\n )}\n {...props}\n >\n {BoundWelcomeScreen}\n </div>\n );\n }\n\n if (children) {\n return (\n <div data-copilotkit style={{ display: \"contents\" }}>\n {children({\n messageView: BoundMessageView,\n input: BoundInput,\n scrollView: BoundScrollView,\n suggestionView: BoundSuggestionView ?? <></>,\n })}\n </div>\n );\n }\n\n return (\n <div\n data-copilotkit\n data-testid=\"copilot-chat\"\n data-copilot-running={isRunning ? \"true\" : \"false\"}\n className={twMerge(\"copilotKitChat cpk:relative cpk:h-full\", className)}\n {...props}\n >\n {BoundScrollView}\n\n {BoundInput}\n </div>\n );\n}\n\nexport namespace CopilotChatView {\n // Inner component that has access to StickToBottom context\n const ScrollContent: React.FC<{\n children: React.ReactNode;\n scrollToBottomButton?: SlotValue<\n React.FC<React.ButtonHTMLAttributes<HTMLButtonElement>>\n >;\n feather?: SlotValue<React.FC<React.HTMLAttributes<HTMLDivElement>>>;\n inputContainerHeight: number;\n isResizing: boolean;\n }> = ({\n children,\n scrollToBottomButton,\n feather,\n inputContainerHeight,\n isResizing,\n }) => {\n const { isAtBottom, scrollToBottom } = useStickToBottomContext();\n\n const BoundFeather = renderSlot(feather, CopilotChatView.Feather, {});\n\n return (\n <>\n <StickToBottom.Content\n className=\"cpk:overflow-y-scroll cpk:overflow-x-hidden\"\n style={{ flex: \"1 1 0%\", minHeight: 0 }}\n >\n <div className=\"cpk:px-4 cpk:sm:px-0 cpk:[div[data-sidebar-chat]_&]:px-8 cpk:[div[data-popup-chat]_&]:px-6\">\n {children}\n </div>\n </StickToBottom.Content>\n\n {/* Feather gradient overlay */}\n {BoundFeather}\n\n {/* Scroll to bottom button - hidden during resize */}\n {!isAtBottom && !isResizing && (\n <div\n className=\"cpk:absolute cpk:inset-x-0 cpk:flex cpk:justify-center cpk:z-30 cpk:pointer-events-none\"\n style={{\n bottom: `${inputContainerHeight + FEATHER_HEIGHT + 16}px`,\n }}\n >\n {renderSlot(\n scrollToBottomButton,\n CopilotChatView.ScrollToBottomButton,\n {\n onClick: () => scrollToBottom(),\n },\n )}\n </div>\n )}\n </>\n );\n };\n\n export const ScrollView: React.FC<\n React.HTMLAttributes<HTMLDivElement> & {\n autoScroll?: boolean;\n scrollToBottomButton?: SlotValue<\n React.FC<React.ButtonHTMLAttributes<HTMLButtonElement>>\n >;\n feather?: SlotValue<React.FC<React.HTMLAttributes<HTMLDivElement>>>;\n inputContainerHeight?: number;\n isResizing?: boolean;\n }\n > = ({\n children,\n autoScroll = true,\n scrollToBottomButton,\n feather,\n inputContainerHeight = 0,\n isResizing = false,\n className,\n ...props\n }) => {\n const [hasMounted, setHasMounted] = useState(false);\n const { scrollRef, contentRef, scrollToBottom } = useStickToBottom();\n const [showScrollButton, setShowScrollButton] = useState(false);\n\n useEffect(() => {\n setHasMounted(true);\n }, []);\n\n // Monitor scroll position for non-autoscroll mode\n useEffect(() => {\n if (autoScroll) return; // Skip for autoscroll mode\n\n const scrollElement = scrollRef.current;\n if (!scrollElement) return;\n\n const checkScroll = () => {\n const atBottom =\n scrollElement.scrollHeight -\n scrollElement.scrollTop -\n scrollElement.clientHeight <\n 10;\n setShowScrollButton(!atBottom);\n };\n\n checkScroll();\n scrollElement.addEventListener(\"scroll\", checkScroll);\n\n // Also check on resize\n const resizeObserver = new ResizeObserver(checkScroll);\n resizeObserver.observe(scrollElement);\n\n return () => {\n scrollElement.removeEventListener(\"scroll\", checkScroll);\n resizeObserver.disconnect();\n };\n }, [scrollRef, autoScroll]);\n\n if (!hasMounted) {\n return (\n <div className=\"cpk:h-full cpk:max-h-full cpk:flex cpk:flex-col cpk:min-h-0 cpk:overflow-y-scroll cpk:overflow-x-hidden\">\n <div className=\"cpk:px-4 cpk:sm:px-0 cpk:[div[data-sidebar-chat]_&]:px-8 cpk:[div[data-popup-chat]_&]:px-6\">\n {children}\n </div>\n </div>\n );\n }\n\n // When autoScroll is false, we don't use StickToBottom\n if (!autoScroll) {\n const BoundFeather = renderSlot(feather, CopilotChatView.Feather, {});\n\n return (\n <div\n ref={scrollRef}\n className={cn(\n \"cpk:h-full cpk:max-h-full cpk:flex cpk:flex-col cpk:min-h-0 cpk:overflow-y-scroll cpk:overflow-x-hidden cpk:relative\",\n className,\n )}\n {...props}\n >\n <div\n ref={contentRef}\n className=\"cpk:px-4 cpk:sm:px-0 cpk:[div[data-sidebar-chat]_&]:px-8 cpk:[div[data-popup-chat]_&]:px-6\"\n >\n {children}\n </div>\n\n {/* Feather gradient overlay */}\n {BoundFeather}\n\n {/* Scroll to bottom button for manual mode */}\n {showScrollButton && !isResizing && (\n <div\n className=\"cpk:absolute cpk:inset-x-0 cpk:flex cpk:justify-center cpk:z-30 cpk:pointer-events-none\"\n style={{\n bottom: `${inputContainerHeight + FEATHER_HEIGHT + 16}px`,\n }}\n >\n {renderSlot(\n scrollToBottomButton,\n CopilotChatView.ScrollToBottomButton,\n {\n onClick: () => scrollToBottom(),\n },\n )}\n </div>\n )}\n </div>\n );\n }\n\n return (\n <StickToBottom\n className={cn(\n \"cpk:h-full cpk:max-h-full cpk:flex cpk:flex-col cpk:min-h-0 cpk:relative\",\n className,\n )}\n resize=\"smooth\"\n initial=\"smooth\"\n {...props}\n >\n <ScrollContent\n scrollToBottomButton={scrollToBottomButton}\n feather={feather}\n inputContainerHeight={inputContainerHeight}\n isResizing={isResizing}\n >\n {children}\n </ScrollContent>\n </StickToBottom>\n );\n };\n\n export const ScrollToBottomButton: React.FC<\n React.ButtonHTMLAttributes<HTMLButtonElement>\n > = ({ className, ...props }) => (\n <Button\n data-testid=\"copilot-scroll-to-bottom\"\n variant=\"outline\"\n size=\"sm\"\n className={twMerge(\n \"cpk:rounded-full cpk:w-10 cpk:h-10 cpk:p-0 cpk:pointer-events-auto\",\n \"cpk:bg-white cpk:dark:bg-gray-900\",\n \"cpk:shadow-lg cpk:border cpk:border-gray-200 cpk:dark:border-gray-700\",\n \"cpk:hover:bg-gray-50 cpk:dark:hover:bg-gray-800\",\n \"cpk:flex cpk:items-center cpk:justify-center cpk:cursor-pointer\",\n className,\n )}\n {...props}\n >\n <ChevronDown className=\"cpk:w-4 cpk:h-4 cpk:text-gray-600 cpk:dark:text-white\" />\n </Button>\n );\n\n export const Feather: React.FC<React.HTMLAttributes<HTMLDivElement>> = ({\n className,\n style,\n ...props\n }) => (\n <div\n className={cn(\n \"cpk:absolute cpk:bottom-0 cpk:left-0 cpk:right-4 cpk:h-24 cpk:pointer-events-none cpk:z-10 cpk:bg-gradient-to-t\",\n \"cpk:from-white cpk:via-white cpk:to-transparent\",\n \"cpk:dark:from-[rgb(33,33,33)] cpk:dark:via-[rgb(33,33,33)]\",\n className,\n )}\n style={style}\n {...props}\n />\n );\n\n export const WelcomeMessage: React.FC<\n React.HTMLAttributes<HTMLDivElement>\n > = ({ className, ...props }) => {\n const config = useCopilotChatConfiguration();\n const labels = config?.labels ?? CopilotChatDefaultLabels;\n\n return (\n <h1\n className={cn(\n \"cpk:text-xl cpk:sm:text-2xl cpk:font-medium cpk:text-foreground cpk:text-center\",\n className,\n )}\n {...props}\n >\n {labels.welcomeMessageText}\n </h1>\n );\n };\n\n export const WelcomeScreen: React.FC<WelcomeScreenProps> = ({\n welcomeMessage,\n input,\n suggestionView,\n className,\n children,\n ...props\n }) => {\n // Render the welcomeMessage slot internally\n const BoundWelcomeMessage = renderSlot(\n welcomeMessage,\n CopilotChatView.WelcomeMessage,\n {},\n );\n\n if (children) {\n return (\n <div data-copilotkit style={{ display: \"contents\" }}>\n {children({\n welcomeMessage: BoundWelcomeMessage,\n input,\n suggestionView,\n className,\n ...props,\n })}\n </div>\n );\n }\n\n return (\n <div\n data-testid=\"copilot-welcome-screen\"\n className={cn(\n \"cpk:flex-1 cpk:flex cpk:flex-col cpk:items-center cpk:justify-center cpk:px-4\",\n className,\n )}\n {...props}\n >\n <div className=\"cpk:w-full cpk:max-w-3xl cpk:flex cpk:flex-col cpk:items-center\">\n {/* Welcome message */}\n <div className=\"cpk:mb-6\">{BoundWelcomeMessage}</div>\n\n {/* Input */}\n <div className=\"cpk:w-full\">{input}</div>\n\n {/* Suggestions */}\n <div className=\"cpk:mt-4 cpk:flex cpk:justify-center\">\n {suggestionView}\n </div>\n </div>\n </div>\n );\n };\n}\n\nexport default CopilotChatView;\n"],"mappings":"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"} |