From 5ad87373708bf14b47cd5919e3ee60b758cb3a42 Mon Sep 17 00:00:00 2001 From: ecwu Date: Fri, 20 Dec 2024 16:07:49 +0800 Subject: [PATCH] Add ExpandableChat component with toggle functionality and customizable dimensions --- src/components/ui/chat/expandable-chat.tsx | 153 +++++++++++++++++++++ 1 file changed, 153 insertions(+) create mode 100644 src/components/ui/chat/expandable-chat.tsx diff --git a/src/components/ui/chat/expandable-chat.tsx b/src/components/ui/chat/expandable-chat.tsx new file mode 100644 index 0000000..58df3eb --- /dev/null +++ b/src/components/ui/chat/expandable-chat.tsx @@ -0,0 +1,153 @@ +"use client"; + +import React, { useRef, useState } from "react"; +import { X, MessageCircle } from "lucide-react"; +import { cn } from "@/lib/utils"; +import { Button } from "@/components/ui/button"; + +export type ChatPosition = "bottom-right" | "bottom-left"; +export type ChatSize = "sm" | "md" | "lg" | "xl" | "full"; + +const chatConfig = { + dimensions: { + sm: "sm:max-w-sm sm:max-h-[500px]", + md: "sm:max-w-md sm:max-h-[600px]", + lg: "sm:max-w-lg sm:max-h-[700px]", + xl: "sm:max-w-xl sm:max-h-[800px]", + full: "sm:w-full sm:h-full", + }, + positions: { + "bottom-right": "bottom-5 right-5", + "bottom-left": "bottom-5 left-5", + }, + chatPositions: { + "bottom-right": "sm:bottom-[calc(100%+10px)] sm:right-0", + "bottom-left": "sm:bottom-[calc(100%+10px)] sm:left-0", + }, + states: { + open: "pointer-events-auto opacity-100 visible scale-100 translate-y-0", + closed: + "pointer-events-none opacity-0 invisible scale-100 sm:translate-y-5", + }, +}; + +interface ExpandableChatProps extends React.HTMLAttributes { + position?: ChatPosition; + size?: ChatSize; + icon?: React.ReactNode; +} + +const ExpandableChat: React.FC = ({ + className, + position = "bottom-right", + size = "md", + icon, + children, + ...props +}) => { + const [isOpen, setIsOpen] = useState(false); + const chatRef = useRef(null); + + const toggleChat = () => setIsOpen(!isOpen); + + return ( +
+
+ {children} + +
+ +
+ ); +}; + +ExpandableChat.displayName = "ExpandableChat"; + +const ExpandableChatHeader: React.FC> = ({ + className, + ...props +}) => ( +
+); + +ExpandableChatHeader.displayName = "ExpandableChatHeader"; + +const ExpandableChatBody: React.FC> = ({ + className, + ...props +}) =>
; + +ExpandableChatBody.displayName = "ExpandableChatBody"; + +const ExpandableChatFooter: React.FC> = ({ + className, + ...props +}) =>
; + +ExpandableChatFooter.displayName = "ExpandableChatFooter"; + +interface ExpandableChatToggleProps + extends React.ButtonHTMLAttributes { + icon?: React.ReactNode; + isOpen: boolean; + toggleChat: () => void; +} + +const ExpandableChatToggle: React.FC = ({ + className, + icon, + isOpen, + toggleChat, + ...props +}) => ( + +); + +ExpandableChatToggle.displayName = "ExpandableChatToggle"; + +export { + ExpandableChat, + ExpandableChatHeader, + ExpandableChatBody, + ExpandableChatFooter, +};