@copilotkitnext/react 1.52.0-next.7 → 1.52.0-next.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/chat/CopilotChatAssistantMessage.cjs +7 -0
- package/dist/components/chat/CopilotChatAssistantMessage.cjs.map +1 -1
- package/dist/components/chat/CopilotChatAssistantMessage.d.cts.map +1 -1
- package/dist/components/chat/CopilotChatAssistantMessage.d.mts.map +1 -1
- package/dist/components/chat/CopilotChatAssistantMessage.mjs +7 -0
- package/dist/components/chat/CopilotChatAssistantMessage.mjs.map +1 -1
- package/dist/components/chat/CopilotChatInput.cjs +7 -0
- package/dist/components/chat/CopilotChatInput.cjs.map +1 -1
- package/dist/components/chat/CopilotChatInput.d.cts.map +1 -1
- package/dist/components/chat/CopilotChatInput.d.mts.map +1 -1
- package/dist/components/chat/CopilotChatInput.mjs +7 -0
- package/dist/components/chat/CopilotChatInput.mjs.map +1 -1
- package/dist/components/chat/CopilotChatMessageView.cjs +2 -0
- package/dist/components/chat/CopilotChatMessageView.cjs.map +1 -1
- package/dist/components/chat/CopilotChatMessageView.d.cts.map +1 -1
- package/dist/components/chat/CopilotChatMessageView.d.mts.map +1 -1
- package/dist/components/chat/CopilotChatMessageView.mjs +2 -0
- package/dist/components/chat/CopilotChatMessageView.mjs.map +1 -1
- package/dist/components/chat/CopilotChatSuggestionPill.cjs +1 -0
- package/dist/components/chat/CopilotChatSuggestionPill.cjs.map +1 -1
- package/dist/components/chat/CopilotChatSuggestionPill.mjs +1 -0
- package/dist/components/chat/CopilotChatSuggestionPill.mjs.map +1 -1
- package/dist/components/chat/CopilotChatSuggestionView.cjs +1 -0
- package/dist/components/chat/CopilotChatSuggestionView.cjs.map +1 -1
- package/dist/components/chat/CopilotChatSuggestionView.d.cts.map +1 -1
- package/dist/components/chat/CopilotChatSuggestionView.d.mts.map +1 -1
- package/dist/components/chat/CopilotChatSuggestionView.mjs +1 -0
- package/dist/components/chat/CopilotChatSuggestionView.mjs.map +1 -1
- package/dist/components/chat/CopilotChatToggleButton.cjs +1 -0
- package/dist/components/chat/CopilotChatToggleButton.cjs.map +1 -1
- package/dist/components/chat/CopilotChatToggleButton.mjs +1 -0
- package/dist/components/chat/CopilotChatToggleButton.mjs.map +1 -1
- package/dist/components/chat/CopilotChatUserMessage.cjs +5 -0
- package/dist/components/chat/CopilotChatUserMessage.cjs.map +1 -1
- package/dist/components/chat/CopilotChatUserMessage.d.cts.map +1 -1
- package/dist/components/chat/CopilotChatUserMessage.d.mts.map +1 -1
- package/dist/components/chat/CopilotChatUserMessage.mjs +5 -0
- package/dist/components/chat/CopilotChatUserMessage.mjs.map +1 -1
- package/dist/components/chat/CopilotChatView.cjs +6 -0
- package/dist/components/chat/CopilotChatView.cjs.map +1 -1
- package/dist/components/chat/CopilotChatView.d.cts.map +1 -1
- package/dist/components/chat/CopilotChatView.d.mts.map +1 -1
- package/dist/components/chat/CopilotChatView.mjs +6 -0
- package/dist/components/chat/CopilotChatView.mjs.map +1 -1
- package/dist/components/chat/CopilotModalHeader.cjs +3 -0
- package/dist/components/chat/CopilotModalHeader.cjs.map +1 -1
- package/dist/components/chat/CopilotModalHeader.d.cts.map +1 -1
- package/dist/components/chat/CopilotModalHeader.d.mts.map +1 -1
- package/dist/components/chat/CopilotModalHeader.mjs +3 -0
- package/dist/components/chat/CopilotModalHeader.mjs.map +1 -1
- package/dist/components/chat/CopilotPopupView.cjs +1 -0
- package/dist/components/chat/CopilotPopupView.cjs.map +1 -1
- package/dist/components/chat/CopilotPopupView.d.cts.map +1 -1
- package/dist/components/chat/CopilotPopupView.d.mts.map +1 -1
- package/dist/components/chat/CopilotPopupView.mjs +1 -0
- package/dist/components/chat/CopilotPopupView.mjs.map +1 -1
- package/dist/components/chat/CopilotSidebarView.cjs +1 -0
- package/dist/components/chat/CopilotSidebarView.cjs.map +1 -1
- package/dist/components/chat/CopilotSidebarView.d.cts.map +1 -1
- package/dist/components/chat/CopilotSidebarView.d.mts.map +1 -1
- package/dist/components/chat/CopilotSidebarView.mjs +1 -0
- package/dist/components/chat/CopilotSidebarView.mjs.map +1 -1
- package/dist/index.umd.js +35 -0
- package/dist/index.umd.js.map +1 -1
- package/package.json +6 -6
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CopilotChatUserMessage.mjs","names":[],"sources":["../../../src/components/chat/CopilotChatUserMessage.tsx"],"sourcesContent":["import { useMemo, useState } from \"react\";\nimport { Copy, Check, Edit, ChevronLeft, ChevronRight } from \"lucide-react\";\nimport {\n useCopilotChatConfiguration,\n CopilotChatDefaultLabels,\n} from \"@/providers/CopilotChatConfigurationProvider\";\nimport { twMerge } from \"tailwind-merge\";\nimport { Button } from \"@/components/ui/button\";\nimport { UserMessage } from \"@ag-ui/core\";\nimport {\n Tooltip,\n TooltipContent,\n TooltipTrigger,\n} from \"@/components/ui/tooltip\";\nimport { renderSlot, WithSlots } from \"@/lib/slots\";\n\nfunction flattenUserMessageContent(content?: UserMessage[\"content\"]): string {\n if (!content) {\n return \"\";\n }\n\n if (typeof content === \"string\") {\n return content;\n }\n\n return content\n .map((part) => {\n if (\n part &&\n typeof part === \"object\" &&\n \"type\" in part &&\n (part as { type?: unknown }).type === \"text\" &&\n typeof (part as { text?: unknown }).text === \"string\"\n ) {\n return (part as { text: string }).text;\n }\n return \"\";\n })\n .filter((text) => text.length > 0)\n .join(\"\\n\");\n}\n\nexport interface CopilotChatUserMessageOnEditMessageProps {\n message: UserMessage;\n}\n\nexport interface CopilotChatUserMessageOnSwitchToBranchProps {\n message: UserMessage;\n branchIndex: number;\n numberOfBranches: number;\n}\n\nexport type CopilotChatUserMessageProps = WithSlots<\n {\n messageRenderer: typeof CopilotChatUserMessage.MessageRenderer;\n toolbar: typeof CopilotChatUserMessage.Toolbar;\n copyButton: typeof CopilotChatUserMessage.CopyButton;\n editButton: typeof CopilotChatUserMessage.EditButton;\n branchNavigation: typeof CopilotChatUserMessage.BranchNavigation;\n },\n {\n onEditMessage?: (props: CopilotChatUserMessageOnEditMessageProps) => void;\n onSwitchToBranch?: (\n props: CopilotChatUserMessageOnSwitchToBranchProps,\n ) => void;\n message: UserMessage;\n branchIndex?: number;\n numberOfBranches?: number;\n additionalToolbarItems?: React.ReactNode;\n } & React.HTMLAttributes<HTMLDivElement>\n>;\n\nexport function CopilotChatUserMessage({\n message,\n onEditMessage,\n branchIndex,\n numberOfBranches,\n onSwitchToBranch,\n additionalToolbarItems,\n messageRenderer,\n toolbar,\n copyButton,\n editButton,\n branchNavigation,\n children,\n className,\n ...props\n}: CopilotChatUserMessageProps) {\n const flattenedContent = useMemo(\n () => flattenUserMessageContent(message.content),\n [message.content],\n );\n\n const BoundMessageRenderer = renderSlot(\n messageRenderer,\n CopilotChatUserMessage.MessageRenderer,\n {\n content: flattenedContent,\n },\n );\n\n const BoundCopyButton = renderSlot(\n copyButton,\n CopilotChatUserMessage.CopyButton,\n {\n onClick: async () => {\n if (flattenedContent) {\n try {\n await navigator.clipboard.writeText(flattenedContent);\n } catch (err) {\n console.error(\"Failed to copy message:\", err);\n }\n }\n },\n },\n );\n\n const BoundEditButton = renderSlot(\n editButton,\n CopilotChatUserMessage.EditButton,\n {\n onClick: () => onEditMessage?.({ message }),\n },\n );\n\n const BoundBranchNavigation = renderSlot(\n branchNavigation,\n CopilotChatUserMessage.BranchNavigation,\n {\n currentBranch: branchIndex,\n numberOfBranches,\n onSwitchToBranch,\n message,\n },\n );\n\n const showBranchNavigation =\n numberOfBranches && numberOfBranches > 1 && onSwitchToBranch;\n\n const BoundToolbar = renderSlot(toolbar, CopilotChatUserMessage.Toolbar, {\n children: (\n <div className=\"cpk:flex cpk:items-center cpk:gap-1 cpk:justify-end\">\n {additionalToolbarItems}\n {BoundCopyButton}\n {onEditMessage && BoundEditButton}\n {showBranchNavigation && BoundBranchNavigation}\n </div>\n ),\n });\n\n if (children) {\n return (\n <div data-copilotkit style={{ display: \"contents\" }}>\n {children({\n messageRenderer: BoundMessageRenderer,\n toolbar: BoundToolbar,\n copyButton: BoundCopyButton,\n editButton: BoundEditButton,\n branchNavigation: BoundBranchNavigation,\n message,\n branchIndex,\n numberOfBranches,\n additionalToolbarItems,\n })}\n </div>\n );\n }\n\n return (\n <div\n data-copilotkit\n className={twMerge(\n \"cpk:flex cpk:flex-col cpk:items-end cpk:group cpk:pt-10\",\n className,\n )}\n data-message-id={message.id}\n {...props}\n >\n {BoundMessageRenderer}\n {BoundToolbar}\n </div>\n );\n}\n\n// eslint-disable-next-line @typescript-eslint/no-namespace\nexport namespace CopilotChatUserMessage {\n export const Container: React.FC<\n React.PropsWithChildren<React.HTMLAttributes<HTMLDivElement>>\n > = ({ children, className, ...props }) => (\n <div\n className={twMerge(\n \"cpk:flex cpk:flex-col cpk:items-end cpk:group\",\n className,\n )}\n {...props}\n >\n {children}\n </div>\n );\n\n export const MessageRenderer: React.FC<{\n content: string;\n className?: string;\n }> = ({ content, className }) => (\n <div\n className={twMerge(\n \"cpk:prose cpk:dark:prose-invert cpk:bg-muted cpk:relative cpk:max-w-[80%] cpk:rounded-[18px] cpk:px-4 cpk:py-1.5 cpk:data-[multiline]:py-3 cpk:inline-block cpk:whitespace-pre-wrap\",\n className,\n )}\n >\n {content}\n </div>\n );\n\n export const Toolbar: React.FC<React.HTMLAttributes<HTMLDivElement>> = ({\n className,\n ...props\n }) => (\n <div\n className={twMerge(\n \"cpk:w-full cpk:bg-transparent cpk:flex cpk:items-center cpk:justify-end cpk:-mr-[5px] cpk:mt-[4px] cpk:invisible cpk:group-hover:visible\",\n className,\n )}\n {...props}\n />\n );\n\n export const ToolbarButton: React.FC<\n React.ButtonHTMLAttributes<HTMLButtonElement> & {\n title: string;\n children: React.ReactNode;\n }\n > = ({ title, children, className, ...props }) => {\n return (\n <Tooltip>\n <TooltipTrigger asChild>\n <Button\n type=\"button\"\n variant=\"assistantMessageToolbarButton\"\n aria-label={title}\n className={twMerge(className)}\n {...props}\n >\n {children}\n </Button>\n </TooltipTrigger>\n <TooltipContent side=\"bottom\">\n <p>{title}</p>\n </TooltipContent>\n </Tooltip>\n );\n };\n\n export const CopyButton: React.FC<\n React.ButtonHTMLAttributes<HTMLButtonElement> & { copied?: boolean }\n > = ({ className, title, onClick, ...props }) => {\n const config = useCopilotChatConfiguration();\n const labels = config?.labels ?? CopilotChatDefaultLabels;\n const [copied, setCopied] = useState(false);\n\n const handleClick = (event: React.MouseEvent<HTMLButtonElement>) => {\n setCopied(true);\n setTimeout(() => setCopied(false), 2000);\n\n if (onClick) {\n onClick(event);\n }\n };\n\n return (\n <ToolbarButton\n title={title || labels.userMessageToolbarCopyMessageLabel}\n onClick={handleClick}\n className={className}\n {...props}\n >\n {copied ? (\n <Check className=\"cpk:size-[18px]\" />\n ) : (\n <Copy className=\"cpk:size-[18px]\" />\n )}\n </ToolbarButton>\n );\n };\n\n export const EditButton: React.FC<\n React.ButtonHTMLAttributes<HTMLButtonElement>\n > = ({ className, title, ...props }) => {\n const config = useCopilotChatConfiguration();\n const labels = config?.labels ?? CopilotChatDefaultLabels;\n return (\n <ToolbarButton\n title={title || labels.userMessageToolbarEditMessageLabel}\n className={className}\n {...props}\n >\n <Edit className=\"cpk:size-[18px]\" />\n </ToolbarButton>\n );\n };\n\n export const BranchNavigation: React.FC<\n React.HTMLAttributes<HTMLDivElement> & {\n currentBranch?: number;\n numberOfBranches?: number;\n onSwitchToBranch?: (\n props: CopilotChatUserMessageOnSwitchToBranchProps,\n ) => void;\n message: UserMessage;\n }\n > = ({\n className,\n currentBranch = 0,\n numberOfBranches = 1,\n onSwitchToBranch,\n message,\n ...props\n }) => {\n if (!numberOfBranches || numberOfBranches <= 1 || !onSwitchToBranch) {\n return null;\n }\n\n const canGoPrev = currentBranch > 0;\n const canGoNext = currentBranch < numberOfBranches - 1;\n\n return (\n <div\n className={twMerge(\"cpk:flex cpk:items-center cpk:gap-1\", className)}\n {...props}\n >\n <Button\n type=\"button\"\n variant=\"assistantMessageToolbarButton\"\n onClick={() =>\n onSwitchToBranch?.({\n branchIndex: currentBranch - 1,\n numberOfBranches,\n message,\n })\n }\n disabled={!canGoPrev}\n className=\"cpk:h-6 cpk:w-6 cpk:p-0\"\n >\n <ChevronLeft className=\"cpk:size-[20px]\" />\n </Button>\n <span className=\"cpk:text-sm cpk:text-muted-foreground cpk:px-0 cpk:font-medium\">\n {currentBranch + 1}/{numberOfBranches}\n </span>\n <Button\n type=\"button\"\n variant=\"assistantMessageToolbarButton\"\n onClick={() =>\n onSwitchToBranch?.({\n branchIndex: currentBranch + 1,\n numberOfBranches,\n message,\n })\n }\n disabled={!canGoNext}\n className=\"cpk:h-6 cpk:w-6 cpk:p-0\"\n >\n <ChevronRight className=\"cpk:size-[20px]\" />\n </Button>\n </div>\n );\n };\n}\n\nCopilotChatUserMessage.Container.displayName =\n \"CopilotChatUserMessage.Container\";\nCopilotChatUserMessage.MessageRenderer.displayName =\n \"CopilotChatUserMessage.MessageRenderer\";\nCopilotChatUserMessage.Toolbar.displayName = \"CopilotChatUserMessage.Toolbar\";\nCopilotChatUserMessage.ToolbarButton.displayName =\n \"CopilotChatUserMessage.ToolbarButton\";\nCopilotChatUserMessage.CopyButton.displayName =\n \"CopilotChatUserMessage.CopyButton\";\nCopilotChatUserMessage.EditButton.displayName =\n \"CopilotChatUserMessage.EditButton\";\nCopilotChatUserMessage.BranchNavigation.displayName =\n \"CopilotChatUserMessage.BranchNavigation\";\n\nexport default CopilotChatUserMessage;\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"CopilotChatUserMessage.mjs","names":[],"sources":["../../../src/components/chat/CopilotChatUserMessage.tsx"],"sourcesContent":["import { useMemo, useState } from \"react\";\nimport { Copy, Check, Edit, ChevronLeft, ChevronRight } from \"lucide-react\";\nimport {\n useCopilotChatConfiguration,\n CopilotChatDefaultLabels,\n} from \"@/providers/CopilotChatConfigurationProvider\";\nimport { twMerge } from \"tailwind-merge\";\nimport { Button } from \"@/components/ui/button\";\nimport { UserMessage } from \"@ag-ui/core\";\nimport {\n Tooltip,\n TooltipContent,\n TooltipTrigger,\n} from \"@/components/ui/tooltip\";\nimport { renderSlot, WithSlots } from \"@/lib/slots\";\n\nfunction flattenUserMessageContent(content?: UserMessage[\"content\"]): string {\n if (!content) {\n return \"\";\n }\n\n if (typeof content === \"string\") {\n return content;\n }\n\n return content\n .map((part) => {\n if (\n part &&\n typeof part === \"object\" &&\n \"type\" in part &&\n (part as { type?: unknown }).type === \"text\" &&\n typeof (part as { text?: unknown }).text === \"string\"\n ) {\n return (part as { text: string }).text;\n }\n return \"\";\n })\n .filter((text) => text.length > 0)\n .join(\"\\n\");\n}\n\nexport interface CopilotChatUserMessageOnEditMessageProps {\n message: UserMessage;\n}\n\nexport interface CopilotChatUserMessageOnSwitchToBranchProps {\n message: UserMessage;\n branchIndex: number;\n numberOfBranches: number;\n}\n\nexport type CopilotChatUserMessageProps = WithSlots<\n {\n messageRenderer: typeof CopilotChatUserMessage.MessageRenderer;\n toolbar: typeof CopilotChatUserMessage.Toolbar;\n copyButton: typeof CopilotChatUserMessage.CopyButton;\n editButton: typeof CopilotChatUserMessage.EditButton;\n branchNavigation: typeof CopilotChatUserMessage.BranchNavigation;\n },\n {\n onEditMessage?: (props: CopilotChatUserMessageOnEditMessageProps) => void;\n onSwitchToBranch?: (\n props: CopilotChatUserMessageOnSwitchToBranchProps,\n ) => void;\n message: UserMessage;\n branchIndex?: number;\n numberOfBranches?: number;\n additionalToolbarItems?: React.ReactNode;\n } & React.HTMLAttributes<HTMLDivElement>\n>;\n\nexport function CopilotChatUserMessage({\n message,\n onEditMessage,\n branchIndex,\n numberOfBranches,\n onSwitchToBranch,\n additionalToolbarItems,\n messageRenderer,\n toolbar,\n copyButton,\n editButton,\n branchNavigation,\n children,\n className,\n ...props\n}: CopilotChatUserMessageProps) {\n const flattenedContent = useMemo(\n () => flattenUserMessageContent(message.content),\n [message.content],\n );\n\n const BoundMessageRenderer = renderSlot(\n messageRenderer,\n CopilotChatUserMessage.MessageRenderer,\n {\n content: flattenedContent,\n },\n );\n\n const BoundCopyButton = renderSlot(\n copyButton,\n CopilotChatUserMessage.CopyButton,\n {\n onClick: async () => {\n if (flattenedContent) {\n try {\n await navigator.clipboard.writeText(flattenedContent);\n } catch (err) {\n console.error(\"Failed to copy message:\", err);\n }\n }\n },\n },\n );\n\n const BoundEditButton = renderSlot(\n editButton,\n CopilotChatUserMessage.EditButton,\n {\n onClick: () => onEditMessage?.({ message }),\n },\n );\n\n const BoundBranchNavigation = renderSlot(\n branchNavigation,\n CopilotChatUserMessage.BranchNavigation,\n {\n currentBranch: branchIndex,\n numberOfBranches,\n onSwitchToBranch,\n message,\n },\n );\n\n const showBranchNavigation =\n numberOfBranches && numberOfBranches > 1 && onSwitchToBranch;\n\n const BoundToolbar = renderSlot(toolbar, CopilotChatUserMessage.Toolbar, {\n children: (\n <div className=\"cpk:flex cpk:items-center cpk:gap-1 cpk:justify-end\">\n {additionalToolbarItems}\n {BoundCopyButton}\n {onEditMessage && BoundEditButton}\n {showBranchNavigation && BoundBranchNavigation}\n </div>\n ),\n });\n\n if (children) {\n return (\n <div data-copilotkit style={{ display: \"contents\" }}>\n {children({\n messageRenderer: BoundMessageRenderer,\n toolbar: BoundToolbar,\n copyButton: BoundCopyButton,\n editButton: BoundEditButton,\n branchNavigation: BoundBranchNavigation,\n message,\n branchIndex,\n numberOfBranches,\n additionalToolbarItems,\n })}\n </div>\n );\n }\n\n return (\n <div\n data-copilotkit\n data-testid=\"copilot-user-message\"\n className={twMerge(\n \"cpk:flex cpk:flex-col cpk:items-end cpk:group cpk:pt-10\",\n className,\n )}\n data-message-id={message.id}\n {...props}\n >\n {BoundMessageRenderer}\n {BoundToolbar}\n </div>\n );\n}\n\n// eslint-disable-next-line @typescript-eslint/no-namespace\nexport namespace CopilotChatUserMessage {\n export const Container: React.FC<\n React.PropsWithChildren<React.HTMLAttributes<HTMLDivElement>>\n > = ({ children, className, ...props }) => (\n <div\n className={twMerge(\n \"cpk:flex cpk:flex-col cpk:items-end cpk:group\",\n className,\n )}\n {...props}\n >\n {children}\n </div>\n );\n\n export const MessageRenderer: React.FC<{\n content: string;\n className?: string;\n }> = ({ content, className }) => (\n <div\n className={twMerge(\n \"cpk:prose cpk:dark:prose-invert cpk:bg-muted cpk:relative cpk:max-w-[80%] cpk:rounded-[18px] cpk:px-4 cpk:py-1.5 cpk:data-[multiline]:py-3 cpk:inline-block cpk:whitespace-pre-wrap\",\n className,\n )}\n >\n {content}\n </div>\n );\n\n export const Toolbar: React.FC<React.HTMLAttributes<HTMLDivElement>> = ({\n className,\n ...props\n }) => (\n <div\n data-testid=\"copilot-user-toolbar\"\n className={twMerge(\n \"cpk:w-full cpk:bg-transparent cpk:flex cpk:items-center cpk:justify-end cpk:-mr-[5px] cpk:mt-[4px] cpk:invisible cpk:group-hover:visible\",\n className,\n )}\n {...props}\n />\n );\n\n export const ToolbarButton: React.FC<\n React.ButtonHTMLAttributes<HTMLButtonElement> & {\n title: string;\n children: React.ReactNode;\n }\n > = ({ title, children, className, ...props }) => {\n return (\n <Tooltip>\n <TooltipTrigger asChild>\n <Button\n type=\"button\"\n variant=\"assistantMessageToolbarButton\"\n aria-label={title}\n className={twMerge(className)}\n {...props}\n >\n {children}\n </Button>\n </TooltipTrigger>\n <TooltipContent side=\"bottom\">\n <p>{title}</p>\n </TooltipContent>\n </Tooltip>\n );\n };\n\n export const CopyButton: React.FC<\n React.ButtonHTMLAttributes<HTMLButtonElement> & { copied?: boolean }\n > = ({ className, title, onClick, ...props }) => {\n const config = useCopilotChatConfiguration();\n const labels = config?.labels ?? CopilotChatDefaultLabels;\n const [copied, setCopied] = useState(false);\n\n const handleClick = (event: React.MouseEvent<HTMLButtonElement>) => {\n setCopied(true);\n setTimeout(() => setCopied(false), 2000);\n\n if (onClick) {\n onClick(event);\n }\n };\n\n return (\n <ToolbarButton\n data-testid=\"copilot-user-copy-button\"\n title={title || labels.userMessageToolbarCopyMessageLabel}\n onClick={handleClick}\n className={className}\n {...props}\n >\n {copied ? (\n <Check className=\"cpk:size-[18px]\" />\n ) : (\n <Copy className=\"cpk:size-[18px]\" />\n )}\n </ToolbarButton>\n );\n };\n\n export const EditButton: React.FC<\n React.ButtonHTMLAttributes<HTMLButtonElement>\n > = ({ className, title, ...props }) => {\n const config = useCopilotChatConfiguration();\n const labels = config?.labels ?? CopilotChatDefaultLabels;\n return (\n <ToolbarButton\n data-testid=\"copilot-edit-button\"\n title={title || labels.userMessageToolbarEditMessageLabel}\n className={className}\n {...props}\n >\n <Edit className=\"cpk:size-[18px]\" />\n </ToolbarButton>\n );\n };\n\n export const BranchNavigation: React.FC<\n React.HTMLAttributes<HTMLDivElement> & {\n currentBranch?: number;\n numberOfBranches?: number;\n onSwitchToBranch?: (\n props: CopilotChatUserMessageOnSwitchToBranchProps,\n ) => void;\n message: UserMessage;\n }\n > = ({\n className,\n currentBranch = 0,\n numberOfBranches = 1,\n onSwitchToBranch,\n message,\n ...props\n }) => {\n if (!numberOfBranches || numberOfBranches <= 1 || !onSwitchToBranch) {\n return null;\n }\n\n const canGoPrev = currentBranch > 0;\n const canGoNext = currentBranch < numberOfBranches - 1;\n\n return (\n <div\n data-testid=\"copilot-branch-navigation\"\n className={twMerge(\"cpk:flex cpk:items-center cpk:gap-1\", className)}\n {...props}\n >\n <Button\n type=\"button\"\n variant=\"assistantMessageToolbarButton\"\n onClick={() =>\n onSwitchToBranch?.({\n branchIndex: currentBranch - 1,\n numberOfBranches,\n message,\n })\n }\n disabled={!canGoPrev}\n className=\"cpk:h-6 cpk:w-6 cpk:p-0\"\n >\n <ChevronLeft className=\"cpk:size-[20px]\" />\n </Button>\n <span className=\"cpk:text-sm cpk:text-muted-foreground cpk:px-0 cpk:font-medium\">\n {currentBranch + 1}/{numberOfBranches}\n </span>\n <Button\n type=\"button\"\n variant=\"assistantMessageToolbarButton\"\n onClick={() =>\n onSwitchToBranch?.({\n branchIndex: currentBranch + 1,\n numberOfBranches,\n message,\n })\n }\n disabled={!canGoNext}\n className=\"cpk:h-6 cpk:w-6 cpk:p-0\"\n >\n <ChevronRight className=\"cpk:size-[20px]\" />\n </Button>\n </div>\n );\n };\n}\n\nCopilotChatUserMessage.Container.displayName =\n \"CopilotChatUserMessage.Container\";\nCopilotChatUserMessage.MessageRenderer.displayName =\n \"CopilotChatUserMessage.MessageRenderer\";\nCopilotChatUserMessage.Toolbar.displayName = \"CopilotChatUserMessage.Toolbar\";\nCopilotChatUserMessage.ToolbarButton.displayName =\n \"CopilotChatUserMessage.ToolbarButton\";\nCopilotChatUserMessage.CopyButton.displayName =\n \"CopilotChatUserMessage.CopyButton\";\nCopilotChatUserMessage.EditButton.displayName =\n \"CopilotChatUserMessage.EditButton\";\nCopilotChatUserMessage.BranchNavigation.displayName =\n \"CopilotChatUserMessage.BranchNavigation\";\n\nexport default CopilotChatUserMessage;\n"],"mappings":"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"}
|
|
@@ -111,6 +111,8 @@ function CopilotChatView({ messageView, input, scrollView, suggestionView, welco
|
|
|
111
111
|
});
|
|
112
112
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
113
113
|
"data-copilotkit": true,
|
|
114
|
+
"data-testid": "copilot-chat",
|
|
115
|
+
"data-copilot-running": isRunning ? "true" : "false",
|
|
114
116
|
className: (0, tailwind_merge.twMerge)("cpk:relative cpk:h-full cpk:flex cpk:flex-col", className),
|
|
115
117
|
...props,
|
|
116
118
|
children: BoundWelcomeScreen
|
|
@@ -128,6 +130,8 @@ function CopilotChatView({ messageView, input, scrollView, suggestionView, welco
|
|
|
128
130
|
});
|
|
129
131
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
130
132
|
"data-copilotkit": true,
|
|
133
|
+
"data-testid": "copilot-chat",
|
|
134
|
+
"data-copilot-running": isRunning ? "true" : "false",
|
|
131
135
|
className: (0, tailwind_merge.twMerge)("cpk:relative cpk:h-full", className),
|
|
132
136
|
...props,
|
|
133
137
|
children: [BoundScrollView, BoundInput]
|
|
@@ -223,6 +227,7 @@ function CopilotChatView({ messageView, input, scrollView, suggestionView, welco
|
|
|
223
227
|
});
|
|
224
228
|
};
|
|
225
229
|
_CopilotChatView.ScrollToBottomButton = ({ className, ...props }) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_button.Button, {
|
|
230
|
+
"data-testid": "copilot-scroll-to-bottom",
|
|
226
231
|
variant: "outline",
|
|
227
232
|
size: "sm",
|
|
228
233
|
className: (0, tailwind_merge.twMerge)("cpk:rounded-full cpk:w-10 cpk:h-10 cpk:p-0 cpk:pointer-events-auto", "cpk:bg-white cpk:dark:bg-gray-900", "cpk:shadow-lg cpk:border cpk:border-gray-200 cpk:dark:border-gray-700", "cpk:hover:bg-gray-50 cpk:dark:hover:bg-gray-800", "cpk:flex cpk:items-center cpk:justify-center cpk:cursor-pointer", className),
|
|
@@ -256,6 +261,7 @@ function CopilotChatView({ messageView, input, scrollView, suggestionView, welco
|
|
|
256
261
|
})
|
|
257
262
|
});
|
|
258
263
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
264
|
+
"data-testid": "copilot-welcome-screen",
|
|
259
265
|
className: require_utils.cn("cpk:flex-1 cpk:flex cpk:flex-col cpk:items-center cpk:justify-center cpk:px-4", className),
|
|
260
266
|
...props,
|
|
261
267
|
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"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 } & 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 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 } 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 } 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 className={twMerge(\n \"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 className={twMerge(\"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 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 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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"}
|
|
1
|
+
{"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 } & 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 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 } 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 } 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 \"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(\"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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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CopilotChatView.d.cts","names":[],"sources":["../../../src/components/chat/CopilotChatView.tsx"],"mappings":";;;;;;;;;;KA+BY,kBAAA,GAAqB,SAAA;EAE7B,cAAA,EAAgB,KAAA,CAAM,EAAA,CAAG,KAAA,CAAM,cAAA,CAAe,cAAA;AAAA;EAG9C,KAAA,EAAO,KAAA,CAAM,YAAA;EACb,cAAA,EAAgB,KAAA,CAAM,YAAA;AAAA,IACpB,KAAA,CAAM,cAAA,CAAe,cAAA;AAAA,KAGf,oBAAA,GAAuB,SAAA;EAE/B,WAAA,SAAoB,sBAAA;EACpB,UAAA,SAAmB,eAAA,CAAgB,UAAA;EACnC,KAAA,SAAc,gBAAA;EACd,cAAA,SAAuB,yBAAA;AAAA;EAGvB,QAAA,GAAW,OAAA;EACX,UAAA;EACA,SAAA;EACA,WAAA,GAAc,UAAA;EACd,wBAAA,GAA2B,aAAA;EAC3B,kBAAA,IAAsB,UAAA,EAAY,UAAA,EAAY,KAAA;EAC9C,aAAA,GAAgB,SAAA,CAAU,KAAA,CAAM,EAAA,CAAG,kBAAA;EAEnC,eAAA,IAAmB,KAAA;EACnB,MAAA;EACA,SAAA,GAAY,oBAAA;EACZ,UAAA;EACA,aAAA,IAAiB,KAAA;EACjB,iBAAA;EACA,kBAAA;EACA,kBAAA;EACA,2BAAA,IAA+B,SAAA,EAAW,IAAA,KAAS,OAAA;AAAA,IACjD,KAAA,CAAM,cAAA,CAAe,cAAA;AAAA,iBAGX,eAAA,CAAA;EACd,WAAA;EACA,KAAA;EACA,UAAA;EACA,cAAA;EACA,aAAA;EACA,QAAA;EACA,UAAA;EACA,SAAA;EACA,WAAA;EACA,wBAAA;EACA,kBAAA;EAEA,eAAA;EACA,MAAA;EACA,SAAA;EACA,UAAA;EACA,aAAA;EACA,iBAAA;EACA,kBAAA;EACA,kBAAA;EACA,2BAAA;EACA,QAAA;EACA,SAAA;EAAA,GACG;AAAA,GACF,oBAAA,GAAoB,kBAAA,CAAA,GAAA,CAAA,OAAA;AAAA,
|
|
1
|
+
{"version":3,"file":"CopilotChatView.d.cts","names":[],"sources":["../../../src/components/chat/CopilotChatView.tsx"],"mappings":";;;;;;;;;;KA+BY,kBAAA,GAAqB,SAAA;EAE7B,cAAA,EAAgB,KAAA,CAAM,EAAA,CAAG,KAAA,CAAM,cAAA,CAAe,cAAA;AAAA;EAG9C,KAAA,EAAO,KAAA,CAAM,YAAA;EACb,cAAA,EAAgB,KAAA,CAAM,YAAA;AAAA,IACpB,KAAA,CAAM,cAAA,CAAe,cAAA;AAAA,KAGf,oBAAA,GAAuB,SAAA;EAE/B,WAAA,SAAoB,sBAAA;EACpB,UAAA,SAAmB,eAAA,CAAgB,UAAA;EACnC,KAAA,SAAc,gBAAA;EACd,cAAA,SAAuB,yBAAA;AAAA;EAGvB,QAAA,GAAW,OAAA;EACX,UAAA;EACA,SAAA;EACA,WAAA,GAAc,UAAA;EACd,wBAAA,GAA2B,aAAA;EAC3B,kBAAA,IAAsB,UAAA,EAAY,UAAA,EAAY,KAAA;EAC9C,aAAA,GAAgB,SAAA,CAAU,KAAA,CAAM,EAAA,CAAG,kBAAA;EAEnC,eAAA,IAAmB,KAAA;EACnB,MAAA;EACA,SAAA,GAAY,oBAAA;EACZ,UAAA;EACA,aAAA,IAAiB,KAAA;EACjB,iBAAA;EACA,kBAAA;EACA,kBAAA;EACA,2BAAA,IAA+B,SAAA,EAAW,IAAA,KAAS,OAAA;AAAA,IACjD,KAAA,CAAM,cAAA,CAAe,cAAA;AAAA,iBAGX,eAAA,CAAA;EACd,WAAA;EACA,KAAA;EACA,UAAA;EACA,cAAA;EACA,aAAA;EACA,QAAA;EACA,UAAA;EACA,SAAA;EACA,WAAA;EACA,wBAAA;EACA,kBAAA;EAEA,eAAA;EACA,MAAA;EACA,SAAA;EACA,UAAA;EACA,aAAA;EACA,iBAAA;EACA,kBAAA;EACA,kBAAA;EACA,2BAAA;EACA,QAAA;EACA,SAAA;EAAA,GACG;AAAA,GACF,oBAAA,GAAoB,kBAAA,CAAA,GAAA,CAAA,OAAA;AAAA,kBA4LN,eAAA;EAAA,MAwDF,UAAA,EAAY,KAAA,CAAM,EAAA,CAC7B,KAAA,CAAM,cAAA,CAAe,cAAA;IACnB,UAAA;IACA,oBAAA,GAAuB,SAAA,CACrB,KAAA,CAAM,EAAA,CAAG,KAAA,CAAM,oBAAA,CAAqB,iBAAA;IAEtC,OAAA,GAAU,SAAA,CAAU,KAAA,CAAM,EAAA,CAAG,KAAA,CAAM,cAAA,CAAe,cAAA;IAClD,oBAAA;IACA,UAAA;EAAA;EAAA,MA6HS,oBAAA,EAAsB,KAAA,CAAM,EAAA,CACvC,KAAA,CAAM,oBAAA,CAAqB,iBAAA;EAAA,MAoBhB,OAAA,EAAS,KAAA,CAAM,EAAA,CAAG,KAAA,CAAM,cAAA,CAAe,cAAA;EAAA,MAiBvC,cAAA,EAAgB,KAAA,CAAM,EAAA,CACjC,KAAA,CAAM,cAAA,CAAe,cAAA;EAAA,MAkBV,aAAA,EAAe,KAAA,CAAM,EAAA,CAAG,kBAAA;AAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CopilotChatView.d.mts","names":[],"sources":["../../../src/components/chat/CopilotChatView.tsx"],"mappings":";;;;;;;;;;KA+BY,kBAAA,GAAqB,SAAA;EAE7B,cAAA,EAAgB,KAAA,CAAM,EAAA,CAAG,KAAA,CAAM,cAAA,CAAe,cAAA;AAAA;EAG9C,KAAA,EAAO,KAAA,CAAM,YAAA;EACb,cAAA,EAAgB,KAAA,CAAM,YAAA;AAAA,IACpB,KAAA,CAAM,cAAA,CAAe,cAAA;AAAA,KAGf,oBAAA,GAAuB,SAAA;EAE/B,WAAA,SAAoB,sBAAA;EACpB,UAAA,SAAmB,eAAA,CAAgB,UAAA;EACnC,KAAA,SAAc,gBAAA;EACd,cAAA,SAAuB,yBAAA;AAAA;EAGvB,QAAA,GAAW,OAAA;EACX,UAAA;EACA,SAAA;EACA,WAAA,GAAc,UAAA;EACd,wBAAA,GAA2B,aAAA;EAC3B,kBAAA,IAAsB,UAAA,EAAY,UAAA,EAAY,KAAA;EAC9C,aAAA,GAAgB,SAAA,CAAU,KAAA,CAAM,EAAA,CAAG,kBAAA;EAEnC,eAAA,IAAmB,KAAA;EACnB,MAAA;EACA,SAAA,GAAY,oBAAA;EACZ,UAAA;EACA,aAAA,IAAiB,KAAA;EACjB,iBAAA;EACA,kBAAA;EACA,kBAAA;EACA,2BAAA,IAA+B,SAAA,EAAW,IAAA,KAAS,OAAA;AAAA,IACjD,KAAA,CAAM,cAAA,CAAe,cAAA;AAAA,iBAGX,eAAA,CAAA;EACd,WAAA;EACA,KAAA;EACA,UAAA;EACA,cAAA;EACA,aAAA;EACA,QAAA;EACA,UAAA;EACA,SAAA;EACA,WAAA;EACA,wBAAA;EACA,kBAAA;EAEA,eAAA;EACA,MAAA;EACA,SAAA;EACA,UAAA;EACA,aAAA;EACA,iBAAA;EACA,kBAAA;EACA,kBAAA;EACA,2BAAA;EACA,QAAA;EACA,SAAA;EAAA,GACG;AAAA,GACF,oBAAA,GAAoB,kBAAA,CAAA,GAAA,CAAA,OAAA;AAAA,
|
|
1
|
+
{"version":3,"file":"CopilotChatView.d.mts","names":[],"sources":["../../../src/components/chat/CopilotChatView.tsx"],"mappings":";;;;;;;;;;KA+BY,kBAAA,GAAqB,SAAA;EAE7B,cAAA,EAAgB,KAAA,CAAM,EAAA,CAAG,KAAA,CAAM,cAAA,CAAe,cAAA;AAAA;EAG9C,KAAA,EAAO,KAAA,CAAM,YAAA;EACb,cAAA,EAAgB,KAAA,CAAM,YAAA;AAAA,IACpB,KAAA,CAAM,cAAA,CAAe,cAAA;AAAA,KAGf,oBAAA,GAAuB,SAAA;EAE/B,WAAA,SAAoB,sBAAA;EACpB,UAAA,SAAmB,eAAA,CAAgB,UAAA;EACnC,KAAA,SAAc,gBAAA;EACd,cAAA,SAAuB,yBAAA;AAAA;EAGvB,QAAA,GAAW,OAAA;EACX,UAAA;EACA,SAAA;EACA,WAAA,GAAc,UAAA;EACd,wBAAA,GAA2B,aAAA;EAC3B,kBAAA,IAAsB,UAAA,EAAY,UAAA,EAAY,KAAA;EAC9C,aAAA,GAAgB,SAAA,CAAU,KAAA,CAAM,EAAA,CAAG,kBAAA;EAEnC,eAAA,IAAmB,KAAA;EACnB,MAAA;EACA,SAAA,GAAY,oBAAA;EACZ,UAAA;EACA,aAAA,IAAiB,KAAA;EACjB,iBAAA;EACA,kBAAA;EACA,kBAAA;EACA,2BAAA,IAA+B,SAAA,EAAW,IAAA,KAAS,OAAA;AAAA,IACjD,KAAA,CAAM,cAAA,CAAe,cAAA;AAAA,iBAGX,eAAA,CAAA;EACd,WAAA;EACA,KAAA;EACA,UAAA;EACA,cAAA;EACA,aAAA;EACA,QAAA;EACA,UAAA;EACA,SAAA;EACA,WAAA;EACA,wBAAA;EACA,kBAAA;EAEA,eAAA;EACA,MAAA;EACA,SAAA;EACA,UAAA;EACA,aAAA;EACA,iBAAA;EACA,kBAAA;EACA,kBAAA;EACA,2BAAA;EACA,QAAA;EACA,SAAA;EAAA,GACG;AAAA,GACF,oBAAA,GAAoB,kBAAA,CAAA,GAAA,CAAA,OAAA;AAAA,kBA4LN,eAAA;EAAA,MAwDF,UAAA,EAAY,KAAA,CAAM,EAAA,CAC7B,KAAA,CAAM,cAAA,CAAe,cAAA;IACnB,UAAA;IACA,oBAAA,GAAuB,SAAA,CACrB,KAAA,CAAM,EAAA,CAAG,KAAA,CAAM,oBAAA,CAAqB,iBAAA;IAEtC,OAAA,GAAU,SAAA,CAAU,KAAA,CAAM,EAAA,CAAG,KAAA,CAAM,cAAA,CAAe,cAAA;IAClD,oBAAA;IACA,UAAA;EAAA;EAAA,MA6HS,oBAAA,EAAsB,KAAA,CAAM,EAAA,CACvC,KAAA,CAAM,oBAAA,CAAqB,iBAAA;EAAA,MAoBhB,OAAA,EAAS,KAAA,CAAM,EAAA,CAAG,KAAA,CAAM,cAAA,CAAe,cAAA;EAAA,MAiBvC,cAAA,EAAgB,KAAA,CAAM,EAAA,CACjC,KAAA,CAAM,cAAA,CAAe,cAAA;EAAA,MAkBV,aAAA,EAAe,KAAA,CAAM,EAAA,CAAG,kBAAA;AAAA"}
|
|
@@ -109,6 +109,8 @@ function CopilotChatView({ messageView, input, scrollView, suggestionView, welco
|
|
|
109
109
|
});
|
|
110
110
|
return /* @__PURE__ */ jsx("div", {
|
|
111
111
|
"data-copilotkit": true,
|
|
112
|
+
"data-testid": "copilot-chat",
|
|
113
|
+
"data-copilot-running": isRunning ? "true" : "false",
|
|
112
114
|
className: twMerge("cpk:relative cpk:h-full cpk:flex cpk:flex-col", className),
|
|
113
115
|
...props,
|
|
114
116
|
children: BoundWelcomeScreen
|
|
@@ -126,6 +128,8 @@ function CopilotChatView({ messageView, input, scrollView, suggestionView, welco
|
|
|
126
128
|
});
|
|
127
129
|
return /* @__PURE__ */ jsxs("div", {
|
|
128
130
|
"data-copilotkit": true,
|
|
131
|
+
"data-testid": "copilot-chat",
|
|
132
|
+
"data-copilot-running": isRunning ? "true" : "false",
|
|
129
133
|
className: twMerge("cpk:relative cpk:h-full", className),
|
|
130
134
|
...props,
|
|
131
135
|
children: [BoundScrollView, BoundInput]
|
|
@@ -221,6 +225,7 @@ function CopilotChatView({ messageView, input, scrollView, suggestionView, welco
|
|
|
221
225
|
});
|
|
222
226
|
};
|
|
223
227
|
_CopilotChatView.ScrollToBottomButton = ({ className, ...props }) => /* @__PURE__ */ jsx(Button, {
|
|
228
|
+
"data-testid": "copilot-scroll-to-bottom",
|
|
224
229
|
variant: "outline",
|
|
225
230
|
size: "sm",
|
|
226
231
|
className: twMerge("cpk:rounded-full cpk:w-10 cpk:h-10 cpk:p-0 cpk:pointer-events-auto", "cpk:bg-white cpk:dark:bg-gray-900", "cpk:shadow-lg cpk:border cpk:border-gray-200 cpk:dark:border-gray-700", "cpk:hover:bg-gray-50 cpk:dark:hover:bg-gray-800", "cpk:flex cpk:items-center cpk:justify-center cpk:cursor-pointer", className),
|
|
@@ -254,6 +259,7 @@ function CopilotChatView({ messageView, input, scrollView, suggestionView, welco
|
|
|
254
259
|
})
|
|
255
260
|
});
|
|
256
261
|
return /* @__PURE__ */ jsx("div", {
|
|
262
|
+
"data-testid": "copilot-welcome-screen",
|
|
257
263
|
className: cn("cpk:flex-1 cpk:flex cpk:flex-col cpk:items-center cpk:justify-center cpk:px-4", className),
|
|
258
264
|
...props,
|
|
259
265
|
children: /* @__PURE__ */ jsxs("div", {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CopilotChatView.mjs","names":["CopilotChatInput"],"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 } & 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 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 } 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 } 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 className={twMerge(\n \"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 className={twMerge(\"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 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 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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"}
|
|
1
|
+
{"version":3,"file":"CopilotChatView.mjs","names":["CopilotChatInput"],"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 } & 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 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 } 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 } 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 \"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(\"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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"}
|
|
@@ -24,6 +24,7 @@ function CopilotModalHeader({ title, titleContent, closeButton, children, classN
|
|
|
24
24
|
...rest
|
|
25
25
|
});
|
|
26
26
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("header", {
|
|
27
|
+
"data-testid": "copilot-modal-header",
|
|
27
28
|
"data-slot": "copilot-modal-header",
|
|
28
29
|
className: require_utils.cn("cpk:flex cpk:items-center cpk:justify-between cpk:border-b cpk:border-border cpk:px-4 cpk:py-4", "cpk:bg-background/95 cpk:backdrop-blur cpk:supports-[backdrop-filter]:bg-background/80", className),
|
|
29
30
|
...rest,
|
|
@@ -49,12 +50,14 @@ function CopilotModalHeader({ title, titleContent, closeButton, children, classN
|
|
|
49
50
|
CopilotModalHeader.displayName = "CopilotModalHeader";
|
|
50
51
|
(function(_CopilotModalHeader) {
|
|
51
52
|
_CopilotModalHeader.Title = ({ children, className, ...props }) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
53
|
+
"data-testid": "copilot-header-title",
|
|
52
54
|
className: require_utils.cn("cpk:w-full cpk:text-base cpk:font-medium cpk:leading-none cpk:tracking-tight cpk:text-foreground", className),
|
|
53
55
|
...props,
|
|
54
56
|
children
|
|
55
57
|
});
|
|
56
58
|
_CopilotModalHeader.CloseButton = ({ className, ...props }) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
57
59
|
type: "button",
|
|
60
|
+
"data-testid": "copilot-close-button",
|
|
58
61
|
className: require_utils.cn("cpk:inline-flex cpk:size-8 cpk:items-center cpk:justify-center cpk:rounded-full cpk:text-muted-foreground cpk:transition cpk:cursor-pointer", "cpk:hover:bg-muted cpk:hover:text-foreground cpk:focus-visible:outline-none cpk:focus-visible:ring-2 cpk:focus-visible:ring-ring", className),
|
|
59
62
|
"aria-label": "Close",
|
|
60
63
|
...props,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CopilotModalHeader.cjs","names":["useCopilotChatConfiguration","CopilotChatDefaultLabels","renderSlot","cn","X"],"sources":["../../../src/components/chat/CopilotModalHeader.tsx"],"sourcesContent":["import React, { useCallback } from \"react\";\n\nimport { cn } from \"@/lib/utils\";\nimport {\n useCopilotChatConfiguration,\n CopilotChatDefaultLabels,\n} from \"@/providers/CopilotChatConfigurationProvider\";\nimport { renderSlot, WithSlots } from \"@/lib/slots\";\nimport { X } from \"lucide-react\";\n\ntype HeaderSlots = {\n titleContent: typeof CopilotModalHeader.Title;\n closeButton: typeof CopilotModalHeader.CloseButton;\n};\n\ntype HeaderRestProps = {\n title?: string;\n} & Omit<React.HTMLAttributes<HTMLDivElement>, \"children\">;\n\nexport type CopilotModalHeaderProps = WithSlots<HeaderSlots, HeaderRestProps>;\n\nexport function CopilotModalHeader({\n title,\n titleContent,\n closeButton,\n children,\n className,\n ...rest\n}: CopilotModalHeaderProps) {\n const configuration = useCopilotChatConfiguration();\n\n const fallbackTitle =\n configuration?.labels.modalHeaderTitle ??\n CopilotChatDefaultLabels.modalHeaderTitle;\n const resolvedTitle = title ?? fallbackTitle;\n\n const handleClose = useCallback(() => {\n configuration?.setModalOpen?.(false);\n }, [configuration]);\n\n const BoundTitle = renderSlot(titleContent, CopilotModalHeader.Title, {\n children: resolvedTitle,\n });\n\n const BoundCloseButton = renderSlot(\n closeButton,\n CopilotModalHeader.CloseButton,\n {\n onClick: handleClose,\n },\n );\n\n if (children) {\n return children({\n titleContent: BoundTitle,\n closeButton: BoundCloseButton,\n title: resolvedTitle,\n ...rest,\n });\n }\n\n return (\n <header\n data-slot=\"copilot-modal-header\"\n className={cn(\n \"cpk:flex cpk:items-center cpk:justify-between cpk:border-b cpk:border-border cpk:px-4 cpk:py-4\",\n \"cpk:bg-background/95 cpk:backdrop-blur cpk:supports-[backdrop-filter]:bg-background/80\",\n className,\n )}\n {...rest}\n >\n <div className=\"cpk:flex cpk:w-full cpk:items-center cpk:gap-2\">\n <div className=\"cpk:flex-1\" aria-hidden=\"true\" />\n <div className=\"cpk:flex cpk:flex-1 cpk:justify-center cpk:text-center\">\n {BoundTitle}\n </div>\n <div className=\"cpk:flex cpk:flex-1 cpk:justify-end\">\n {BoundCloseButton}\n </div>\n </div>\n </header>\n );\n}\n\nCopilotModalHeader.displayName = \"CopilotModalHeader\";\n\nexport namespace CopilotModalHeader {\n export const Title: React.FC<React.HTMLAttributes<HTMLDivElement>> = ({\n children,\n className,\n ...props\n }) => (\n <div\n className={cn(\n \"cpk:w-full cpk:text-base cpk:font-medium cpk:leading-none cpk:tracking-tight cpk:text-foreground\",\n className,\n )}\n {...props}\n >\n {children}\n </div>\n );\n\n export const CloseButton: React.FC<\n React.ButtonHTMLAttributes<HTMLButtonElement>\n > = ({ className, ...props }) => (\n <button\n type=\"button\"\n className={cn(\n \"cpk:inline-flex cpk:size-8 cpk:items-center cpk:justify-center cpk:rounded-full cpk:text-muted-foreground cpk:transition cpk:cursor-pointer\",\n \"cpk:hover:bg-muted cpk:hover:text-foreground cpk:focus-visible:outline-none cpk:focus-visible:ring-2 cpk:focus-visible:ring-ring\",\n className,\n )}\n aria-label=\"Close\"\n {...props}\n >\n <X className=\"cpk:h-4 cpk:w-4\" aria-hidden=\"true\" />\n </button>\n );\n}\n\nCopilotModalHeader.Title.displayName = \"CopilotModalHeader.Title\";\nCopilotModalHeader.CloseButton.displayName = \"CopilotModalHeader.CloseButton\";\n\nexport default CopilotModalHeader;\n"],"mappings":";;;;;;;;;;AAqBA,SAAgB,mBAAmB,EACjC,OACA,cACA,aACA,UACA,WACA,GAAG,QACuB;CAC1B,MAAM,gBAAgBA,sEAA6B;CAEnD,MAAM,gBACJ,eAAe,OAAO,oBACtBC,kEAAyB;CAC3B,MAAM,gBAAgB,SAAS;CAE/B,MAAM,2CAAgC;AACpC,iBAAe,eAAe,MAAM;IACnC,CAAC,cAAc,CAAC;CAEnB,MAAM,aAAaC,yBAAW,cAAc,mBAAmB,OAAO,EACpE,UAAU,eACX,CAAC;CAEF,MAAM,mBAAmBA,yBACvB,aACA,mBAAmB,aACnB,EACE,SAAS,aACV,CACF;AAED,KAAI,SACF,QAAO,SAAS;EACd,cAAc;EACd,aAAa;EACb,OAAO;EACP,GAAG;EACJ,CAAC;AAGJ,QACE,2CAAC;EACC,aAAU;EACV,WAAWC,iBACT,kGACA,0FACA,UACD;EACD,GAAI;YAEJ,4CAAC;GAAI,WAAU;;IACb,2CAAC;KAAI,WAAU;KAAa,eAAY;MAAS;IACjD,2CAAC;KAAI,WAAU;eACZ;MACG;IACN,2CAAC;KAAI,WAAU;eACZ;MACG;;IACF;GACC;;AAIb,mBAAmB,cAAc;;8BAGuC,EACpE,UACA,WACA,GAAG,YAEH,2CAAC;EACC,WAAWA,iBACT,oGACA,UACD;EACD,GAAI;EAEH;GACG;oCAKH,EAAE,WAAW,GAAG,YACnB,2CAAC;EACC,MAAK;EACL,WAAWA,iBACT,+IACA,oIACA,UACD;EACD,cAAW;EACX,GAAI;YAEJ,2CAACC;GAAE,WAAU;GAAkB,eAAY;IAAS;GAC7C;;AAIb,mBAAmB,MAAM,cAAc;AACvC,mBAAmB,YAAY,cAAc"}
|
|
1
|
+
{"version":3,"file":"CopilotModalHeader.cjs","names":["useCopilotChatConfiguration","CopilotChatDefaultLabels","renderSlot","cn","X"],"sources":["../../../src/components/chat/CopilotModalHeader.tsx"],"sourcesContent":["import React, { useCallback } from \"react\";\n\nimport { cn } from \"@/lib/utils\";\nimport {\n useCopilotChatConfiguration,\n CopilotChatDefaultLabels,\n} from \"@/providers/CopilotChatConfigurationProvider\";\nimport { renderSlot, WithSlots } from \"@/lib/slots\";\nimport { X } from \"lucide-react\";\n\ntype HeaderSlots = {\n titleContent: typeof CopilotModalHeader.Title;\n closeButton: typeof CopilotModalHeader.CloseButton;\n};\n\ntype HeaderRestProps = {\n title?: string;\n} & Omit<React.HTMLAttributes<HTMLDivElement>, \"children\">;\n\nexport type CopilotModalHeaderProps = WithSlots<HeaderSlots, HeaderRestProps>;\n\nexport function CopilotModalHeader({\n title,\n titleContent,\n closeButton,\n children,\n className,\n ...rest\n}: CopilotModalHeaderProps) {\n const configuration = useCopilotChatConfiguration();\n\n const fallbackTitle =\n configuration?.labels.modalHeaderTitle ??\n CopilotChatDefaultLabels.modalHeaderTitle;\n const resolvedTitle = title ?? fallbackTitle;\n\n const handleClose = useCallback(() => {\n configuration?.setModalOpen?.(false);\n }, [configuration]);\n\n const BoundTitle = renderSlot(titleContent, CopilotModalHeader.Title, {\n children: resolvedTitle,\n });\n\n const BoundCloseButton = renderSlot(\n closeButton,\n CopilotModalHeader.CloseButton,\n {\n onClick: handleClose,\n },\n );\n\n if (children) {\n return children({\n titleContent: BoundTitle,\n closeButton: BoundCloseButton,\n title: resolvedTitle,\n ...rest,\n });\n }\n\n return (\n <header\n data-testid=\"copilot-modal-header\"\n data-slot=\"copilot-modal-header\"\n className={cn(\n \"cpk:flex cpk:items-center cpk:justify-between cpk:border-b cpk:border-border cpk:px-4 cpk:py-4\",\n \"cpk:bg-background/95 cpk:backdrop-blur cpk:supports-[backdrop-filter]:bg-background/80\",\n className,\n )}\n {...rest}\n >\n <div className=\"cpk:flex cpk:w-full cpk:items-center cpk:gap-2\">\n <div className=\"cpk:flex-1\" aria-hidden=\"true\" />\n <div className=\"cpk:flex cpk:flex-1 cpk:justify-center cpk:text-center\">\n {BoundTitle}\n </div>\n <div className=\"cpk:flex cpk:flex-1 cpk:justify-end\">\n {BoundCloseButton}\n </div>\n </div>\n </header>\n );\n}\n\nCopilotModalHeader.displayName = \"CopilotModalHeader\";\n\nexport namespace CopilotModalHeader {\n export const Title: React.FC<React.HTMLAttributes<HTMLDivElement>> = ({\n children,\n className,\n ...props\n }) => (\n <div\n data-testid=\"copilot-header-title\"\n className={cn(\n \"cpk:w-full cpk:text-base cpk:font-medium cpk:leading-none cpk:tracking-tight cpk:text-foreground\",\n className,\n )}\n {...props}\n >\n {children}\n </div>\n );\n\n export const CloseButton: React.FC<\n React.ButtonHTMLAttributes<HTMLButtonElement>\n > = ({ className, ...props }) => (\n <button\n type=\"button\"\n data-testid=\"copilot-close-button\"\n className={cn(\n \"cpk:inline-flex cpk:size-8 cpk:items-center cpk:justify-center cpk:rounded-full cpk:text-muted-foreground cpk:transition cpk:cursor-pointer\",\n \"cpk:hover:bg-muted cpk:hover:text-foreground cpk:focus-visible:outline-none cpk:focus-visible:ring-2 cpk:focus-visible:ring-ring\",\n className,\n )}\n aria-label=\"Close\"\n {...props}\n >\n <X className=\"cpk:h-4 cpk:w-4\" aria-hidden=\"true\" />\n </button>\n );\n}\n\nCopilotModalHeader.Title.displayName = \"CopilotModalHeader.Title\";\nCopilotModalHeader.CloseButton.displayName = \"CopilotModalHeader.CloseButton\";\n\nexport default CopilotModalHeader;\n"],"mappings":";;;;;;;;;;AAqBA,SAAgB,mBAAmB,EACjC,OACA,cACA,aACA,UACA,WACA,GAAG,QACuB;CAC1B,MAAM,gBAAgBA,sEAA6B;CAEnD,MAAM,gBACJ,eAAe,OAAO,oBACtBC,kEAAyB;CAC3B,MAAM,gBAAgB,SAAS;CAE/B,MAAM,2CAAgC;AACpC,iBAAe,eAAe,MAAM;IACnC,CAAC,cAAc,CAAC;CAEnB,MAAM,aAAaC,yBAAW,cAAc,mBAAmB,OAAO,EACpE,UAAU,eACX,CAAC;CAEF,MAAM,mBAAmBA,yBACvB,aACA,mBAAmB,aACnB,EACE,SAAS,aACV,CACF;AAED,KAAI,SACF,QAAO,SAAS;EACd,cAAc;EACd,aAAa;EACb,OAAO;EACP,GAAG;EACJ,CAAC;AAGJ,QACE,2CAAC;EACC,eAAY;EACZ,aAAU;EACV,WAAWC,iBACT,kGACA,0FACA,UACD;EACD,GAAI;YAEJ,4CAAC;GAAI,WAAU;;IACb,2CAAC;KAAI,WAAU;KAAa,eAAY;MAAS;IACjD,2CAAC;KAAI,WAAU;eACZ;MACG;IACN,2CAAC;KAAI,WAAU;eACZ;MACG;;IACF;GACC;;AAIb,mBAAmB,cAAc;;8BAGuC,EACpE,UACA,WACA,GAAG,YAEH,2CAAC;EACC,eAAY;EACZ,WAAWA,iBACT,oGACA,UACD;EACD,GAAI;EAEH;GACG;oCAKH,EAAE,WAAW,GAAG,YACnB,2CAAC;EACC,MAAK;EACL,eAAY;EACZ,WAAWA,iBACT,+IACA,oIACA,UACD;EACD,cAAW;EACX,GAAI;YAEJ,2CAACC;GAAE,WAAU;GAAkB,eAAY;IAAS;GAC7C;;AAIb,mBAAmB,MAAM,cAAc;AACvC,mBAAmB,YAAY,cAAc"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CopilotModalHeader.d.cts","names":[],"sources":["../../../src/components/chat/CopilotModalHeader.tsx"],"mappings":";;;;;KAUK,WAAA;EACH,YAAA,SAAqB,kBAAA,CAAmB,KAAA;EACxC,WAAA,SAAoB,kBAAA,CAAmB,WAAA;AAAA;AAAA,KAGpC,eAAA;EACH,KAAA;AAAA,IACE,IAAA,CAAK,KAAA,CAAM,cAAA,CAAe,cAAA;AAAA,KAElB,uBAAA,GAA0B,SAAA,CAAU,WAAA,EAAa,eAAA;AAAA,iBAE7C,kBAAA,CAAA;EACd,KAAA;EACA,YAAA;EACA,WAAA;EACA,QAAA;EACA,SAAA;EAAA,GACG;AAAA,GACF,uBAAA,wCAAuB,kBAAA,CAAA,GAAA,CAAA,OAAA,GAAA,QAAA,CAAA,KAAA,CAAA,SAAA,IAAA,OAAA,sCAAA,KAAA,CAAA,WAAA,GAAA,KAAA,CAAA,YAAA,mBAAA,KAAA,CAAA,qBAAA,SAAA,QAAA,CAAA,KAAA,CAAA,SAAA;AAAA,kBAPV,kBAAA;EAAA,IAAkB,WAAA;AAAA;AAAA,
|
|
1
|
+
{"version":3,"file":"CopilotModalHeader.d.cts","names":[],"sources":["../../../src/components/chat/CopilotModalHeader.tsx"],"mappings":";;;;;KAUK,WAAA;EACH,YAAA,SAAqB,kBAAA,CAAmB,KAAA;EACxC,WAAA,SAAoB,kBAAA,CAAmB,WAAA;AAAA;AAAA,KAGpC,eAAA;EACH,KAAA;AAAA,IACE,IAAA,CAAK,KAAA,CAAM,cAAA,CAAe,cAAA;AAAA,KAElB,uBAAA,GAA0B,SAAA,CAAU,WAAA,EAAa,eAAA;AAAA,iBAE7C,kBAAA,CAAA;EACd,KAAA;EACA,YAAA;EACA,WAAA;EACA,QAAA;EACA,SAAA;EAAA,GACG;AAAA,GACF,uBAAA,wCAAuB,kBAAA,CAAA,GAAA,CAAA,OAAA,GAAA,QAAA,CAAA,KAAA,CAAA,SAAA,IAAA,OAAA,sCAAA,KAAA,CAAA,WAAA,GAAA,KAAA,CAAA,YAAA,mBAAA,KAAA,CAAA,qBAAA,SAAA,QAAA,CAAA,KAAA,CAAA,SAAA;AAAA,kBAPV,kBAAA;EAAA,IAAkB,WAAA;AAAA;AAAA,kBAkEjB,kBAAA;EAAA,MACF,KAAA,EAAO,KAAA,CAAM,EAAA,CAAG,KAAA,CAAM,cAAA,CAAe,cAAA;EAAA,MAiBrC,WAAA,EAAa,KAAA,CAAM,EAAA,CAC9B,KAAA,CAAM,oBAAA,CAAqB,iBAAA;AAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CopilotModalHeader.d.mts","names":[],"sources":["../../../src/components/chat/CopilotModalHeader.tsx"],"mappings":";;;;;KAUK,WAAA;EACH,YAAA,SAAqB,kBAAA,CAAmB,KAAA;EACxC,WAAA,SAAoB,kBAAA,CAAmB,WAAA;AAAA;AAAA,KAGpC,eAAA;EACH,KAAA;AAAA,IACE,IAAA,CAAK,KAAA,CAAM,cAAA,CAAe,cAAA;AAAA,KAElB,uBAAA,GAA0B,SAAA,CAAU,WAAA,EAAa,eAAA;AAAA,iBAE7C,kBAAA,CAAA;EACd,KAAA;EACA,YAAA;EACA,WAAA;EACA,QAAA;EACA,SAAA;EAAA,GACG;AAAA,GACF,uBAAA,wCAAuB,kBAAA,CAAA,GAAA,CAAA,OAAA,GAAA,QAAA,CAAA,KAAA,CAAA,SAAA,IAAA,OAAA,sCAAA,KAAA,CAAA,WAAA,GAAA,KAAA,CAAA,YAAA,mBAAA,KAAA,CAAA,qBAAA,SAAA,QAAA,CAAA,KAAA,CAAA,SAAA;AAAA,kBAPV,kBAAA;EAAA,IAAkB,WAAA;AAAA;AAAA,
|
|
1
|
+
{"version":3,"file":"CopilotModalHeader.d.mts","names":[],"sources":["../../../src/components/chat/CopilotModalHeader.tsx"],"mappings":";;;;;KAUK,WAAA;EACH,YAAA,SAAqB,kBAAA,CAAmB,KAAA;EACxC,WAAA,SAAoB,kBAAA,CAAmB,WAAA;AAAA;AAAA,KAGpC,eAAA;EACH,KAAA;AAAA,IACE,IAAA,CAAK,KAAA,CAAM,cAAA,CAAe,cAAA;AAAA,KAElB,uBAAA,GAA0B,SAAA,CAAU,WAAA,EAAa,eAAA;AAAA,iBAE7C,kBAAA,CAAA;EACd,KAAA;EACA,YAAA;EACA,WAAA;EACA,QAAA;EACA,SAAA;EAAA,GACG;AAAA,GACF,uBAAA,wCAAuB,kBAAA,CAAA,GAAA,CAAA,OAAA,GAAA,QAAA,CAAA,KAAA,CAAA,SAAA,IAAA,OAAA,sCAAA,KAAA,CAAA,WAAA,GAAA,KAAA,CAAA,YAAA,mBAAA,KAAA,CAAA,qBAAA,SAAA,QAAA,CAAA,KAAA,CAAA,SAAA;AAAA,kBAPV,kBAAA;EAAA,IAAkB,WAAA;AAAA;AAAA,kBAkEjB,kBAAA;EAAA,MACF,KAAA,EAAO,KAAA,CAAM,EAAA,CAAG,KAAA,CAAM,cAAA,CAAe,cAAA;EAAA,MAiBrC,WAAA,EAAa,KAAA,CAAM,EAAA,CAC9B,KAAA,CAAM,oBAAA,CAAqB,iBAAA;AAAA"}
|
|
@@ -22,6 +22,7 @@ function CopilotModalHeader({ title, titleContent, closeButton, children, classN
|
|
|
22
22
|
...rest
|
|
23
23
|
});
|
|
24
24
|
return /* @__PURE__ */ jsx("header", {
|
|
25
|
+
"data-testid": "copilot-modal-header",
|
|
25
26
|
"data-slot": "copilot-modal-header",
|
|
26
27
|
className: cn("cpk:flex cpk:items-center cpk:justify-between cpk:border-b cpk:border-border cpk:px-4 cpk:py-4", "cpk:bg-background/95 cpk:backdrop-blur cpk:supports-[backdrop-filter]:bg-background/80", className),
|
|
27
28
|
...rest,
|
|
@@ -47,12 +48,14 @@ function CopilotModalHeader({ title, titleContent, closeButton, children, classN
|
|
|
47
48
|
CopilotModalHeader.displayName = "CopilotModalHeader";
|
|
48
49
|
(function(_CopilotModalHeader) {
|
|
49
50
|
_CopilotModalHeader.Title = ({ children, className, ...props }) => /* @__PURE__ */ jsx("div", {
|
|
51
|
+
"data-testid": "copilot-header-title",
|
|
50
52
|
className: cn("cpk:w-full cpk:text-base cpk:font-medium cpk:leading-none cpk:tracking-tight cpk:text-foreground", className),
|
|
51
53
|
...props,
|
|
52
54
|
children
|
|
53
55
|
});
|
|
54
56
|
_CopilotModalHeader.CloseButton = ({ className, ...props }) => /* @__PURE__ */ jsx("button", {
|
|
55
57
|
type: "button",
|
|
58
|
+
"data-testid": "copilot-close-button",
|
|
56
59
|
className: cn("cpk:inline-flex cpk:size-8 cpk:items-center cpk:justify-center cpk:rounded-full cpk:text-muted-foreground cpk:transition cpk:cursor-pointer", "cpk:hover:bg-muted cpk:hover:text-foreground cpk:focus-visible:outline-none cpk:focus-visible:ring-2 cpk:focus-visible:ring-ring", className),
|
|
57
60
|
"aria-label": "Close",
|
|
58
61
|
...props,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CopilotModalHeader.mjs","names":[],"sources":["../../../src/components/chat/CopilotModalHeader.tsx"],"sourcesContent":["import React, { useCallback } from \"react\";\n\nimport { cn } from \"@/lib/utils\";\nimport {\n useCopilotChatConfiguration,\n CopilotChatDefaultLabels,\n} from \"@/providers/CopilotChatConfigurationProvider\";\nimport { renderSlot, WithSlots } from \"@/lib/slots\";\nimport { X } from \"lucide-react\";\n\ntype HeaderSlots = {\n titleContent: typeof CopilotModalHeader.Title;\n closeButton: typeof CopilotModalHeader.CloseButton;\n};\n\ntype HeaderRestProps = {\n title?: string;\n} & Omit<React.HTMLAttributes<HTMLDivElement>, \"children\">;\n\nexport type CopilotModalHeaderProps = WithSlots<HeaderSlots, HeaderRestProps>;\n\nexport function CopilotModalHeader({\n title,\n titleContent,\n closeButton,\n children,\n className,\n ...rest\n}: CopilotModalHeaderProps) {\n const configuration = useCopilotChatConfiguration();\n\n const fallbackTitle =\n configuration?.labels.modalHeaderTitle ??\n CopilotChatDefaultLabels.modalHeaderTitle;\n const resolvedTitle = title ?? fallbackTitle;\n\n const handleClose = useCallback(() => {\n configuration?.setModalOpen?.(false);\n }, [configuration]);\n\n const BoundTitle = renderSlot(titleContent, CopilotModalHeader.Title, {\n children: resolvedTitle,\n });\n\n const BoundCloseButton = renderSlot(\n closeButton,\n CopilotModalHeader.CloseButton,\n {\n onClick: handleClose,\n },\n );\n\n if (children) {\n return children({\n titleContent: BoundTitle,\n closeButton: BoundCloseButton,\n title: resolvedTitle,\n ...rest,\n });\n }\n\n return (\n <header\n data-slot=\"copilot-modal-header\"\n className={cn(\n \"cpk:flex cpk:items-center cpk:justify-between cpk:border-b cpk:border-border cpk:px-4 cpk:py-4\",\n \"cpk:bg-background/95 cpk:backdrop-blur cpk:supports-[backdrop-filter]:bg-background/80\",\n className,\n )}\n {...rest}\n >\n <div className=\"cpk:flex cpk:w-full cpk:items-center cpk:gap-2\">\n <div className=\"cpk:flex-1\" aria-hidden=\"true\" />\n <div className=\"cpk:flex cpk:flex-1 cpk:justify-center cpk:text-center\">\n {BoundTitle}\n </div>\n <div className=\"cpk:flex cpk:flex-1 cpk:justify-end\">\n {BoundCloseButton}\n </div>\n </div>\n </header>\n );\n}\n\nCopilotModalHeader.displayName = \"CopilotModalHeader\";\n\nexport namespace CopilotModalHeader {\n export const Title: React.FC<React.HTMLAttributes<HTMLDivElement>> = ({\n children,\n className,\n ...props\n }) => (\n <div\n className={cn(\n \"cpk:w-full cpk:text-base cpk:font-medium cpk:leading-none cpk:tracking-tight cpk:text-foreground\",\n className,\n )}\n {...props}\n >\n {children}\n </div>\n );\n\n export const CloseButton: React.FC<\n React.ButtonHTMLAttributes<HTMLButtonElement>\n > = ({ className, ...props }) => (\n <button\n type=\"button\"\n className={cn(\n \"cpk:inline-flex cpk:size-8 cpk:items-center cpk:justify-center cpk:rounded-full cpk:text-muted-foreground cpk:transition cpk:cursor-pointer\",\n \"cpk:hover:bg-muted cpk:hover:text-foreground cpk:focus-visible:outline-none cpk:focus-visible:ring-2 cpk:focus-visible:ring-ring\",\n className,\n )}\n aria-label=\"Close\"\n {...props}\n >\n <X className=\"cpk:h-4 cpk:w-4\" aria-hidden=\"true\" />\n </button>\n );\n}\n\nCopilotModalHeader.Title.displayName = \"CopilotModalHeader.Title\";\nCopilotModalHeader.CloseButton.displayName = \"CopilotModalHeader.CloseButton\";\n\nexport default CopilotModalHeader;\n"],"mappings":";;;;;;;;AAqBA,SAAgB,mBAAmB,EACjC,OACA,cACA,aACA,UACA,WACA,GAAG,QACuB;CAC1B,MAAM,gBAAgB,6BAA6B;CAEnD,MAAM,gBACJ,eAAe,OAAO,oBACtB,yBAAyB;CAC3B,MAAM,gBAAgB,SAAS;CAE/B,MAAM,cAAc,kBAAkB;AACpC,iBAAe,eAAe,MAAM;IACnC,CAAC,cAAc,CAAC;CAEnB,MAAM,aAAa,WAAW,cAAc,mBAAmB,OAAO,EACpE,UAAU,eACX,CAAC;CAEF,MAAM,mBAAmB,WACvB,aACA,mBAAmB,aACnB,EACE,SAAS,aACV,CACF;AAED,KAAI,SACF,QAAO,SAAS;EACd,cAAc;EACd,aAAa;EACb,OAAO;EACP,GAAG;EACJ,CAAC;AAGJ,QACE,oBAAC;EACC,aAAU;EACV,WAAW,GACT,kGACA,0FACA,UACD;EACD,GAAI;YAEJ,qBAAC;GAAI,WAAU;;IACb,oBAAC;KAAI,WAAU;KAAa,eAAY;MAAS;IACjD,oBAAC;KAAI,WAAU;eACZ;MACG;IACN,oBAAC;KAAI,WAAU;eACZ;MACG;;IACF;GACC;;AAIb,mBAAmB,cAAc;;8BAGuC,EACpE,UACA,WACA,GAAG,YAEH,oBAAC;EACC,WAAW,GACT,oGACA,UACD;EACD,GAAI;EAEH;GACG;oCAKH,EAAE,WAAW,GAAG,YACnB,oBAAC;EACC,MAAK;EACL,WAAW,GACT,+IACA,oIACA,UACD;EACD,cAAW;EACX,GAAI;YAEJ,oBAAC;GAAE,WAAU;GAAkB,eAAY;IAAS;GAC7C;;AAIb,mBAAmB,MAAM,cAAc;AACvC,mBAAmB,YAAY,cAAc"}
|
|
1
|
+
{"version":3,"file":"CopilotModalHeader.mjs","names":[],"sources":["../../../src/components/chat/CopilotModalHeader.tsx"],"sourcesContent":["import React, { useCallback } from \"react\";\n\nimport { cn } from \"@/lib/utils\";\nimport {\n useCopilotChatConfiguration,\n CopilotChatDefaultLabels,\n} from \"@/providers/CopilotChatConfigurationProvider\";\nimport { renderSlot, WithSlots } from \"@/lib/slots\";\nimport { X } from \"lucide-react\";\n\ntype HeaderSlots = {\n titleContent: typeof CopilotModalHeader.Title;\n closeButton: typeof CopilotModalHeader.CloseButton;\n};\n\ntype HeaderRestProps = {\n title?: string;\n} & Omit<React.HTMLAttributes<HTMLDivElement>, \"children\">;\n\nexport type CopilotModalHeaderProps = WithSlots<HeaderSlots, HeaderRestProps>;\n\nexport function CopilotModalHeader({\n title,\n titleContent,\n closeButton,\n children,\n className,\n ...rest\n}: CopilotModalHeaderProps) {\n const configuration = useCopilotChatConfiguration();\n\n const fallbackTitle =\n configuration?.labels.modalHeaderTitle ??\n CopilotChatDefaultLabels.modalHeaderTitle;\n const resolvedTitle = title ?? fallbackTitle;\n\n const handleClose = useCallback(() => {\n configuration?.setModalOpen?.(false);\n }, [configuration]);\n\n const BoundTitle = renderSlot(titleContent, CopilotModalHeader.Title, {\n children: resolvedTitle,\n });\n\n const BoundCloseButton = renderSlot(\n closeButton,\n CopilotModalHeader.CloseButton,\n {\n onClick: handleClose,\n },\n );\n\n if (children) {\n return children({\n titleContent: BoundTitle,\n closeButton: BoundCloseButton,\n title: resolvedTitle,\n ...rest,\n });\n }\n\n return (\n <header\n data-testid=\"copilot-modal-header\"\n data-slot=\"copilot-modal-header\"\n className={cn(\n \"cpk:flex cpk:items-center cpk:justify-between cpk:border-b cpk:border-border cpk:px-4 cpk:py-4\",\n \"cpk:bg-background/95 cpk:backdrop-blur cpk:supports-[backdrop-filter]:bg-background/80\",\n className,\n )}\n {...rest}\n >\n <div className=\"cpk:flex cpk:w-full cpk:items-center cpk:gap-2\">\n <div className=\"cpk:flex-1\" aria-hidden=\"true\" />\n <div className=\"cpk:flex cpk:flex-1 cpk:justify-center cpk:text-center\">\n {BoundTitle}\n </div>\n <div className=\"cpk:flex cpk:flex-1 cpk:justify-end\">\n {BoundCloseButton}\n </div>\n </div>\n </header>\n );\n}\n\nCopilotModalHeader.displayName = \"CopilotModalHeader\";\n\nexport namespace CopilotModalHeader {\n export const Title: React.FC<React.HTMLAttributes<HTMLDivElement>> = ({\n children,\n className,\n ...props\n }) => (\n <div\n data-testid=\"copilot-header-title\"\n className={cn(\n \"cpk:w-full cpk:text-base cpk:font-medium cpk:leading-none cpk:tracking-tight cpk:text-foreground\",\n className,\n )}\n {...props}\n >\n {children}\n </div>\n );\n\n export const CloseButton: React.FC<\n React.ButtonHTMLAttributes<HTMLButtonElement>\n > = ({ className, ...props }) => (\n <button\n type=\"button\"\n data-testid=\"copilot-close-button\"\n className={cn(\n \"cpk:inline-flex cpk:size-8 cpk:items-center cpk:justify-center cpk:rounded-full cpk:text-muted-foreground cpk:transition cpk:cursor-pointer\",\n \"cpk:hover:bg-muted cpk:hover:text-foreground cpk:focus-visible:outline-none cpk:focus-visible:ring-2 cpk:focus-visible:ring-ring\",\n className,\n )}\n aria-label=\"Close\"\n {...props}\n >\n <X className=\"cpk:h-4 cpk:w-4\" aria-hidden=\"true\" />\n </button>\n );\n}\n\nCopilotModalHeader.Title.displayName = \"CopilotModalHeader.Title\";\nCopilotModalHeader.CloseButton.displayName = \"CopilotModalHeader.CloseButton\";\n\nexport default CopilotModalHeader;\n"],"mappings":";;;;;;;;AAqBA,SAAgB,mBAAmB,EACjC,OACA,cACA,aACA,UACA,WACA,GAAG,QACuB;CAC1B,MAAM,gBAAgB,6BAA6B;CAEnD,MAAM,gBACJ,eAAe,OAAO,oBACtB,yBAAyB;CAC3B,MAAM,gBAAgB,SAAS;CAE/B,MAAM,cAAc,kBAAkB;AACpC,iBAAe,eAAe,MAAM;IACnC,CAAC,cAAc,CAAC;CAEnB,MAAM,aAAa,WAAW,cAAc,mBAAmB,OAAO,EACpE,UAAU,eACX,CAAC;CAEF,MAAM,mBAAmB,WACvB,aACA,mBAAmB,aACnB,EACE,SAAS,aACV,CACF;AAED,KAAI,SACF,QAAO,SAAS;EACd,cAAc;EACd,aAAa;EACb,OAAO;EACP,GAAG;EACJ,CAAC;AAGJ,QACE,oBAAC;EACC,eAAY;EACZ,aAAU;EACV,WAAW,GACT,kGACA,0FACA,UACD;EACD,GAAI;YAEJ,qBAAC;GAAI,WAAU;;IACb,oBAAC;KAAI,WAAU;KAAa,eAAY;MAAS;IACjD,oBAAC;KAAI,WAAU;eACZ;MACG;IACN,oBAAC;KAAI,WAAU;eACZ;MACG;;IACF;GACC;;AAIb,mBAAmB,cAAc;;8BAGuC,EACpE,UACA,WACA,GAAG,YAEH,oBAAC;EACC,eAAY;EACZ,WAAW,GACT,oGACA,UACD;EACD,GAAI;EAEH;GACG;oCAKH,EAAE,WAAW,GAAG,YACnB,oBAAC;EACC,MAAK;EACL,eAAY;EACZ,WAAW,GACT,+IACA,oIACA,UACD;EACD,cAAW;EACX,GAAI;YAEJ,oBAAC;GAAE,WAAU;GAAkB,eAAY;IAAS;GAC7C;;AAIb,mBAAmB,MAAM,cAAc;AACvC,mBAAmB,YAAY,cAAc"}
|
|
@@ -114,6 +114,7 @@ function CopilotPopupViewInternal({ header, toggleButton, width, height, clickOu
|
|
|
114
114
|
tabIndex: -1,
|
|
115
115
|
role: "dialog",
|
|
116
116
|
"aria-label": labels.modalHeaderTitle,
|
|
117
|
+
"data-testid": "copilot-popup",
|
|
117
118
|
"data-copilot-popup": true,
|
|
118
119
|
className: require_utils.cn("cpk:relative cpk:flex cpk:h-full cpk:w-full cpk:flex-col cpk:overflow-hidden cpk:bg-background cpk:text-foreground", "cpk:origin-bottom cpk:focus:outline-none cpk:transform-gpu cpk:transition-transform cpk:transition-opacity cpk:duration-200 cpk:ease-out", "cpk:md:transition-transform cpk:md:transition-opacity", "cpk:rounded-none cpk:border cpk:border-border/0 cpk:shadow-none cpk:ring-0", "cpk:md:h-[var(--copilot-popup-height)] cpk:md:w-[var(--copilot-popup-width)]", "cpk:md:max-h-[var(--copilot-popup-max-height)] cpk:md:max-w-[var(--copilot-popup-max-width)]", "cpk:md:origin-bottom-right cpk:md:rounded-2xl cpk:md:border-border cpk:md:shadow-xl cpk:md:ring-1 cpk:md:ring-border/40", popupAnimationClass),
|
|
119
120
|
style: popupStyle,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CopilotPopupView.cjs","names":["CopilotChatConfigurationProvider","useCopilotChatConfiguration","CopilotChatDefaultLabels","renderSlot","CopilotModalHeader","CopilotChatToggleButton","cn","CopilotChatView"],"sources":["../../../src/components/chat/CopilotPopupView.tsx"],"sourcesContent":["import React, { useEffect, useMemo, useRef, useState } from \"react\";\nimport CopilotChatView, {\n CopilotChatViewProps,\n WelcomeScreenProps,\n} from \"./CopilotChatView\";\nimport CopilotChatToggleButton from \"./CopilotChatToggleButton\";\nimport { CopilotModalHeader } from \"./CopilotModalHeader\";\nimport { cn } from \"@/lib/utils\";\nimport { renderSlot, SlotValue } from \"@/lib/slots\";\nimport {\n CopilotChatConfigurationProvider,\n CopilotChatDefaultLabels,\n useCopilotChatConfiguration,\n} from \"@/providers/CopilotChatConfigurationProvider\";\n\nconst DEFAULT_POPUP_WIDTH = 420;\nconst DEFAULT_POPUP_HEIGHT = 560;\n\nexport type CopilotPopupViewProps = CopilotChatViewProps & {\n header?: SlotValue<typeof CopilotModalHeader>;\n toggleButton?: SlotValue<typeof CopilotChatToggleButton>;\n width?: number | string;\n height?: number | string;\n clickOutsideToClose?: boolean;\n defaultOpen?: boolean;\n};\n\nconst dimensionToCss = (\n value: number | string | undefined,\n fallback: number,\n): string => {\n if (typeof value === \"number\" && Number.isFinite(value)) {\n return `${value}px`;\n }\n\n if (typeof value === \"string\" && value.trim().length > 0) {\n return value;\n }\n\n return `${fallback}px`;\n};\n\nexport function CopilotPopupView({\n header,\n toggleButton,\n width,\n height,\n clickOutsideToClose,\n defaultOpen = true,\n className,\n ...restProps\n}: CopilotPopupViewProps) {\n return (\n <CopilotChatConfigurationProvider isModalDefaultOpen={defaultOpen}>\n <CopilotPopupViewInternal\n header={header}\n toggleButton={toggleButton}\n width={width}\n height={height}\n clickOutsideToClose={clickOutsideToClose}\n className={className}\n {...restProps}\n />\n </CopilotChatConfigurationProvider>\n );\n}\n\nfunction CopilotPopupViewInternal({\n header,\n toggleButton,\n width,\n height,\n clickOutsideToClose,\n className,\n ...restProps\n}: Omit<CopilotPopupViewProps, \"defaultOpen\">) {\n const configuration = useCopilotChatConfiguration();\n const isPopupOpen = configuration?.isModalOpen ?? false;\n const setModalOpen = configuration?.setModalOpen;\n const labels = configuration?.labels ?? CopilotChatDefaultLabels;\n\n const containerRef = useRef<HTMLDivElement>(null);\n const [isRendered, setIsRendered] = useState(isPopupOpen);\n const [isAnimatingOut, setIsAnimatingOut] = useState(false);\n\n useEffect(() => {\n if (isPopupOpen) {\n setIsRendered(true);\n setIsAnimatingOut(false);\n return;\n }\n\n if (!isRendered) {\n return;\n }\n\n setIsAnimatingOut(true);\n const timeout = setTimeout(() => {\n setIsRendered(false);\n setIsAnimatingOut(false);\n }, 200);\n\n return () => clearTimeout(timeout);\n }, [isPopupOpen, isRendered]);\n\n useEffect(() => {\n if (!isPopupOpen) {\n return;\n }\n\n if (typeof window === \"undefined\") {\n return;\n }\n\n const handleKeyDown = (event: KeyboardEvent) => {\n if (event.key === \"Escape\") {\n event.preventDefault();\n setModalOpen?.(false);\n }\n };\n\n window.addEventListener(\"keydown\", handleKeyDown);\n return () => window.removeEventListener(\"keydown\", handleKeyDown);\n }, [isPopupOpen, setModalOpen]);\n\n useEffect(() => {\n if (!isPopupOpen) {\n return;\n }\n\n const focusTimer = setTimeout(() => {\n const container = containerRef.current;\n // Don't steal focus if something inside the popup (like the input) is already focused\n if (container && !container.contains(document.activeElement)) {\n container.focus({ preventScroll: true });\n }\n }, 200);\n\n return () => clearTimeout(focusTimer);\n }, [isPopupOpen]);\n\n useEffect(() => {\n if (!isPopupOpen || !clickOutsideToClose) {\n return;\n }\n\n if (typeof document === \"undefined\") {\n return;\n }\n\n const handlePointerDown = (event: PointerEvent) => {\n const target = event.target as Node | null;\n if (!target) {\n return;\n }\n\n const container = containerRef.current;\n if (container?.contains(target)) {\n return;\n }\n\n const toggleButton = document.querySelector(\n \"[data-slot='chat-toggle-button']\",\n );\n if (toggleButton && toggleButton.contains(target)) {\n return;\n }\n\n setModalOpen?.(false);\n };\n\n document.addEventListener(\"pointerdown\", handlePointerDown);\n return () => document.removeEventListener(\"pointerdown\", handlePointerDown);\n }, [isPopupOpen, clickOutsideToClose, setModalOpen]);\n\n const headerElement = useMemo(\n () => renderSlot(header, CopilotModalHeader, {}),\n [header],\n );\n const toggleButtonElement = useMemo(\n () => renderSlot(toggleButton, CopilotChatToggleButton, {}),\n [toggleButton],\n );\n\n const resolvedWidth = dimensionToCss(width, DEFAULT_POPUP_WIDTH);\n const resolvedHeight = dimensionToCss(height, DEFAULT_POPUP_HEIGHT);\n\n const popupStyle = useMemo(\n () =>\n ({\n \"--copilot-popup-width\": resolvedWidth,\n \"--copilot-popup-height\": resolvedHeight,\n \"--copilot-popup-max-width\": \"calc(100vw - 3rem)\",\n \"--copilot-popup-max-height\": \"calc(100dvh - 7.5rem)\",\n paddingTop: \"env(safe-area-inset-top)\",\n paddingBottom: \"env(safe-area-inset-bottom)\",\n paddingLeft: \"env(safe-area-inset-left)\",\n paddingRight: \"env(safe-area-inset-right)\",\n }) as React.CSSProperties,\n [resolvedHeight, resolvedWidth],\n );\n\n const popupAnimationClass =\n isPopupOpen && !isAnimatingOut\n ? \"cpk:pointer-events-auto cpk:translate-y-0 cpk:opacity-100 cpk:md:scale-100\"\n : \"cpk:pointer-events-none cpk:translate-y-4 cpk:opacity-0 cpk:md:translate-y-5 cpk:md:scale-[0.95]\";\n\n const popupContent = isRendered ? (\n <div\n data-copilotkit\n className={cn(\n \"cpk:fixed cpk:inset-0 cpk:z-[1200] cpk:flex cpk:max-w-full cpk:flex-col cpk:items-stretch\",\n \"cpk:md:inset-auto cpk:md:bottom-24 cpk:md:right-6 cpk:md:items-end cpk:md:gap-4\",\n )}\n >\n <div\n ref={containerRef}\n tabIndex={-1}\n role=\"dialog\"\n aria-label={labels.modalHeaderTitle}\n data-copilot-popup\n className={cn(\n \"cpk:relative cpk:flex cpk:h-full cpk:w-full cpk:flex-col cpk:overflow-hidden cpk:bg-background cpk:text-foreground\",\n \"cpk:origin-bottom cpk:focus:outline-none cpk:transform-gpu cpk:transition-transform cpk:transition-opacity cpk:duration-200 cpk:ease-out\",\n \"cpk:md:transition-transform cpk:md:transition-opacity\",\n \"cpk:rounded-none cpk:border cpk:border-border/0 cpk:shadow-none cpk:ring-0\",\n \"cpk:md:h-[var(--copilot-popup-height)] cpk:md:w-[var(--copilot-popup-width)]\",\n \"cpk:md:max-h-[var(--copilot-popup-max-height)] cpk:md:max-w-[var(--copilot-popup-max-width)]\",\n \"cpk:md:origin-bottom-right cpk:md:rounded-2xl cpk:md:border-border cpk:md:shadow-xl cpk:md:ring-1 cpk:md:ring-border/40\",\n popupAnimationClass,\n )}\n style={popupStyle}\n >\n {headerElement}\n <div className=\"cpk:flex-1 cpk:overflow-hidden\" data-popup-chat>\n <CopilotChatView\n {...restProps}\n className={cn(\"cpk:h-full cpk:min-h-0\", className)}\n />\n </div>\n </div>\n </div>\n ) : null;\n\n return (\n <>\n {toggleButtonElement}\n {popupContent}\n </>\n );\n}\n\nCopilotPopupView.displayName = \"CopilotPopupView\";\n\n// eslint-disable-next-line @typescript-eslint/no-namespace\nexport namespace CopilotPopupView {\n /**\n * Popup-specific welcome screen layout:\n * - Welcome message centered vertically\n * - Suggestions just above input\n * - Input fixed at the bottom\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 className={cn(\"cpk:h-full cpk:flex cpk:flex-col\", className)}\n {...props}\n >\n {/* Welcome message - centered vertically */}\n <div className=\"cpk:flex-1 cpk:flex cpk:flex-col cpk:items-center cpk:justify-center cpk:px-4\">\n {BoundWelcomeMessage}\n </div>\n\n {/* Suggestions and input at bottom */}\n <div>\n {/* Suggestions above input */}\n <div className=\"cpk:mb-4 cpk:flex cpk:justify-center cpk:px-4\">\n {suggestionView}\n </div>\n {input}\n </div>\n </div>\n );\n };\n}\n\nexport default CopilotPopupView;\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"CopilotPopupView.cjs","names":["CopilotChatConfigurationProvider","useCopilotChatConfiguration","CopilotChatDefaultLabels","renderSlot","CopilotModalHeader","CopilotChatToggleButton","cn","CopilotChatView"],"sources":["../../../src/components/chat/CopilotPopupView.tsx"],"sourcesContent":["import React, { useEffect, useMemo, useRef, useState } from \"react\";\nimport CopilotChatView, {\n CopilotChatViewProps,\n WelcomeScreenProps,\n} from \"./CopilotChatView\";\nimport CopilotChatToggleButton from \"./CopilotChatToggleButton\";\nimport { CopilotModalHeader } from \"./CopilotModalHeader\";\nimport { cn } from \"@/lib/utils\";\nimport { renderSlot, SlotValue } from \"@/lib/slots\";\nimport {\n CopilotChatConfigurationProvider,\n CopilotChatDefaultLabels,\n useCopilotChatConfiguration,\n} from \"@/providers/CopilotChatConfigurationProvider\";\n\nconst DEFAULT_POPUP_WIDTH = 420;\nconst DEFAULT_POPUP_HEIGHT = 560;\n\nexport type CopilotPopupViewProps = CopilotChatViewProps & {\n header?: SlotValue<typeof CopilotModalHeader>;\n toggleButton?: SlotValue<typeof CopilotChatToggleButton>;\n width?: number | string;\n height?: number | string;\n clickOutsideToClose?: boolean;\n defaultOpen?: boolean;\n};\n\nconst dimensionToCss = (\n value: number | string | undefined,\n fallback: number,\n): string => {\n if (typeof value === \"number\" && Number.isFinite(value)) {\n return `${value}px`;\n }\n\n if (typeof value === \"string\" && value.trim().length > 0) {\n return value;\n }\n\n return `${fallback}px`;\n};\n\nexport function CopilotPopupView({\n header,\n toggleButton,\n width,\n height,\n clickOutsideToClose,\n defaultOpen = true,\n className,\n ...restProps\n}: CopilotPopupViewProps) {\n return (\n <CopilotChatConfigurationProvider isModalDefaultOpen={defaultOpen}>\n <CopilotPopupViewInternal\n header={header}\n toggleButton={toggleButton}\n width={width}\n height={height}\n clickOutsideToClose={clickOutsideToClose}\n className={className}\n {...restProps}\n />\n </CopilotChatConfigurationProvider>\n );\n}\n\nfunction CopilotPopupViewInternal({\n header,\n toggleButton,\n width,\n height,\n clickOutsideToClose,\n className,\n ...restProps\n}: Omit<CopilotPopupViewProps, \"defaultOpen\">) {\n const configuration = useCopilotChatConfiguration();\n const isPopupOpen = configuration?.isModalOpen ?? false;\n const setModalOpen = configuration?.setModalOpen;\n const labels = configuration?.labels ?? CopilotChatDefaultLabels;\n\n const containerRef = useRef<HTMLDivElement>(null);\n const [isRendered, setIsRendered] = useState(isPopupOpen);\n const [isAnimatingOut, setIsAnimatingOut] = useState(false);\n\n useEffect(() => {\n if (isPopupOpen) {\n setIsRendered(true);\n setIsAnimatingOut(false);\n return;\n }\n\n if (!isRendered) {\n return;\n }\n\n setIsAnimatingOut(true);\n const timeout = setTimeout(() => {\n setIsRendered(false);\n setIsAnimatingOut(false);\n }, 200);\n\n return () => clearTimeout(timeout);\n }, [isPopupOpen, isRendered]);\n\n useEffect(() => {\n if (!isPopupOpen) {\n return;\n }\n\n if (typeof window === \"undefined\") {\n return;\n }\n\n const handleKeyDown = (event: KeyboardEvent) => {\n if (event.key === \"Escape\") {\n event.preventDefault();\n setModalOpen?.(false);\n }\n };\n\n window.addEventListener(\"keydown\", handleKeyDown);\n return () => window.removeEventListener(\"keydown\", handleKeyDown);\n }, [isPopupOpen, setModalOpen]);\n\n useEffect(() => {\n if (!isPopupOpen) {\n return;\n }\n\n const focusTimer = setTimeout(() => {\n const container = containerRef.current;\n // Don't steal focus if something inside the popup (like the input) is already focused\n if (container && !container.contains(document.activeElement)) {\n container.focus({ preventScroll: true });\n }\n }, 200);\n\n return () => clearTimeout(focusTimer);\n }, [isPopupOpen]);\n\n useEffect(() => {\n if (!isPopupOpen || !clickOutsideToClose) {\n return;\n }\n\n if (typeof document === \"undefined\") {\n return;\n }\n\n const handlePointerDown = (event: PointerEvent) => {\n const target = event.target as Node | null;\n if (!target) {\n return;\n }\n\n const container = containerRef.current;\n if (container?.contains(target)) {\n return;\n }\n\n const toggleButton = document.querySelector(\n \"[data-slot='chat-toggle-button']\",\n );\n if (toggleButton && toggleButton.contains(target)) {\n return;\n }\n\n setModalOpen?.(false);\n };\n\n document.addEventListener(\"pointerdown\", handlePointerDown);\n return () => document.removeEventListener(\"pointerdown\", handlePointerDown);\n }, [isPopupOpen, clickOutsideToClose, setModalOpen]);\n\n const headerElement = useMemo(\n () => renderSlot(header, CopilotModalHeader, {}),\n [header],\n );\n const toggleButtonElement = useMemo(\n () => renderSlot(toggleButton, CopilotChatToggleButton, {}),\n [toggleButton],\n );\n\n const resolvedWidth = dimensionToCss(width, DEFAULT_POPUP_WIDTH);\n const resolvedHeight = dimensionToCss(height, DEFAULT_POPUP_HEIGHT);\n\n const popupStyle = useMemo(\n () =>\n ({\n \"--copilot-popup-width\": resolvedWidth,\n \"--copilot-popup-height\": resolvedHeight,\n \"--copilot-popup-max-width\": \"calc(100vw - 3rem)\",\n \"--copilot-popup-max-height\": \"calc(100dvh - 7.5rem)\",\n paddingTop: \"env(safe-area-inset-top)\",\n paddingBottom: \"env(safe-area-inset-bottom)\",\n paddingLeft: \"env(safe-area-inset-left)\",\n paddingRight: \"env(safe-area-inset-right)\",\n }) as React.CSSProperties,\n [resolvedHeight, resolvedWidth],\n );\n\n const popupAnimationClass =\n isPopupOpen && !isAnimatingOut\n ? \"cpk:pointer-events-auto cpk:translate-y-0 cpk:opacity-100 cpk:md:scale-100\"\n : \"cpk:pointer-events-none cpk:translate-y-4 cpk:opacity-0 cpk:md:translate-y-5 cpk:md:scale-[0.95]\";\n\n const popupContent = isRendered ? (\n <div\n data-copilotkit\n className={cn(\n \"cpk:fixed cpk:inset-0 cpk:z-[1200] cpk:flex cpk:max-w-full cpk:flex-col cpk:items-stretch\",\n \"cpk:md:inset-auto cpk:md:bottom-24 cpk:md:right-6 cpk:md:items-end cpk:md:gap-4\",\n )}\n >\n <div\n ref={containerRef}\n tabIndex={-1}\n role=\"dialog\"\n aria-label={labels.modalHeaderTitle}\n data-testid=\"copilot-popup\"\n data-copilot-popup\n className={cn(\n \"cpk:relative cpk:flex cpk:h-full cpk:w-full cpk:flex-col cpk:overflow-hidden cpk:bg-background cpk:text-foreground\",\n \"cpk:origin-bottom cpk:focus:outline-none cpk:transform-gpu cpk:transition-transform cpk:transition-opacity cpk:duration-200 cpk:ease-out\",\n \"cpk:md:transition-transform cpk:md:transition-opacity\",\n \"cpk:rounded-none cpk:border cpk:border-border/0 cpk:shadow-none cpk:ring-0\",\n \"cpk:md:h-[var(--copilot-popup-height)] cpk:md:w-[var(--copilot-popup-width)]\",\n \"cpk:md:max-h-[var(--copilot-popup-max-height)] cpk:md:max-w-[var(--copilot-popup-max-width)]\",\n \"cpk:md:origin-bottom-right cpk:md:rounded-2xl cpk:md:border-border cpk:md:shadow-xl cpk:md:ring-1 cpk:md:ring-border/40\",\n popupAnimationClass,\n )}\n style={popupStyle}\n >\n {headerElement}\n <div className=\"cpk:flex-1 cpk:overflow-hidden\" data-popup-chat>\n <CopilotChatView\n {...restProps}\n className={cn(\"cpk:h-full cpk:min-h-0\", className)}\n />\n </div>\n </div>\n </div>\n ) : null;\n\n return (\n <>\n {toggleButtonElement}\n {popupContent}\n </>\n );\n}\n\nCopilotPopupView.displayName = \"CopilotPopupView\";\n\n// eslint-disable-next-line @typescript-eslint/no-namespace\nexport namespace CopilotPopupView {\n /**\n * Popup-specific welcome screen layout:\n * - Welcome message centered vertically\n * - Suggestions just above input\n * - Input fixed at the bottom\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 className={cn(\"cpk:h-full cpk:flex cpk:flex-col\", className)}\n {...props}\n >\n {/* Welcome message - centered vertically */}\n <div className=\"cpk:flex-1 cpk:flex cpk:flex-col cpk:items-center cpk:justify-center cpk:px-4\">\n {BoundWelcomeMessage}\n </div>\n\n {/* Suggestions and input at bottom */}\n <div>\n {/* Suggestions above input */}\n <div className=\"cpk:mb-4 cpk:flex cpk:justify-center cpk:px-4\">\n {suggestionView}\n </div>\n {input}\n </div>\n </div>\n );\n };\n}\n\nexport default CopilotPopupView;\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CopilotPopupView.d.cts","names":[],"sources":["../../../src/components/chat/CopilotPopupView.tsx"],"mappings":";;;;;;;;KAkBY,qBAAA,GAAwB,oBAAA;EAClC,MAAA,GAAS,SAAA,QAAiB,kBAAA;EAC1B,YAAA,GAAe,SAAA,QAAiB,uBAAA;EAChC,KAAA;EACA,MAAA;EACA,mBAAA;EACA,WAAA;AAAA;AAAA,iBAkBc,gBAAA,CAAA;EACd,MAAA;EACA,YAAA;EACA,KAAA;EACA,MAAA;EACA,mBAAA;EACA,WAAA;EACA,SAAA;EAAA,GACG;AAAA,GACF,qBAAA,GAAqB,kBAAA,CAAA,GAAA,CAAA,OAAA;AAAA,kBATR,gBAAA;EAAA,IAAgB,WAAA;AAAA;AAAA,
|
|
1
|
+
{"version":3,"file":"CopilotPopupView.d.cts","names":[],"sources":["../../../src/components/chat/CopilotPopupView.tsx"],"mappings":";;;;;;;;KAkBY,qBAAA,GAAwB,oBAAA;EAClC,MAAA,GAAS,SAAA,QAAiB,kBAAA;EAC1B,YAAA,GAAe,SAAA,QAAiB,uBAAA;EAChC,KAAA;EACA,MAAA;EACA,mBAAA;EACA,WAAA;AAAA;AAAA,iBAkBc,gBAAA,CAAA;EACd,MAAA;EACA,YAAA;EACA,KAAA;EACA,MAAA;EACA,mBAAA;EACA,WAAA;EACA,SAAA;EAAA,GACG;AAAA,GACF,qBAAA,GAAqB,kBAAA,CAAA,GAAA,CAAA,OAAA;AAAA,kBATR,gBAAA;EAAA,IAAgB,WAAA;AAAA;AAAA,kBAsNf,gBAAA;EA9OmB;;;;;;EAAA,MAqPrB,aAAA,EAAe,KAAA,CAAM,EAAA,CAAG,kBAAA;AAAA"}
|