diff --git a/extensions/react-widget/src/components/DocsGPTWidget.tsx b/extensions/react-widget/src/components/DocsGPTWidget.tsx index 53923fb8..69980359 100644 --- a/extensions/react-widget/src/components/DocsGPTWidget.tsx +++ b/extensions/react-widget/src/components/DocsGPTWidget.tsx @@ -60,18 +60,48 @@ const Overlay = styled.div` z-index: 999; transition: opacity 0.5s; ` -const WidgetContainer = styled.div<{ modal?: boolean }>` +const WidgetContainer = styled.div<{ modal?: boolean, isOpen?: boolean }>` all: initial; position: fixed; right: ${props => props.modal ? '50%' : '10px'}; bottom: ${props => props.modal ? '50%' : '10px'}; z-index: 1000; - display: block; + display: none; + transform-origin:100% 100%; + &.open { + animation: createBox 250ms cubic-bezier(0.25, 0.1, 0.25, 1) forwards; + } + &.close { + animation: closeBox 250ms cubic-bezier(0.25, 0.1, 0.25, 1) forwards; + } ${props => props.modal && "transform : translate(50%,50%);" } align-items: center; text-align: left; + @keyframes createBox { + 0% { + transform: scale(0.5); + } + 90% { + transform: scale(1.02); + } + 100% { + transform: scale(1); + } + } + + @keyframes closeBox { + 0% { + transform: scale(1); + } + 10% { + transform: scale(1.02); + } + 100% { + transform: scale(0); + } + } `; const StyledContainer = styled.div` all: initial; @@ -97,16 +127,19 @@ const StyledContainer = styled.div` overflow: auto; } `; -const FloatingButton = styled.div<{ bgcolor: string }>` +const FloatingButton = styled.div<{ bgcolor: string, hidden: boolean }>` position: fixed; - display: flex; + display: ${props => props.hidden ? "none" : "flex"}; z-index: 500; justify-content: center; + gap: 8px; + padding: 14px; align-items: center; bottom: 16px; + color: white; + font-family: sans-serif; right: 16px; - width: 80px; - height: 80px; + font-weight: 500; border-radius: 9999px; background: ${props => props.bgcolor}; box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1); @@ -388,7 +421,8 @@ export const DocsGPTWidget = ({ heroDescription = 'This chatbot is built with DocsGPT and utilises GenAI, please review important information using sources.', size = 'small', theme = 'dark', - buttonIcon = 'https://d3dg1063dc54p9.cloudfront.net/widget/message.svg', + buttonIcon = 'https://d3dg1063dc54p9.cloudfront.net/widget/chat.svg', + buttonText = 'Ask a question', buttonBg = 'linear-gradient(to bottom right, #5AF0EC, #E80D9D)', collectFeedback = true, deafultOpen = false @@ -400,6 +434,7 @@ export const DocsGPTWidget = ({ const [open, setOpen] = React.useState(deafultOpen) const [eventInterrupt, setEventInterrupt] = React.useState(false); //click or scroll by user while autoScrolling const isBubbleHovered = useRef(false) + const widgetRef = useRef(null) const endMessageRef = React.useRef(null); const md = new MarkdownIt(); @@ -511,25 +546,38 @@ export const DocsGPTWidget = ({ const handleImageError = (event: React.SyntheticEvent) => { event.currentTarget.src = "https://d3dg1063dc54p9.cloudfront.net/cute-docsgpt.png"; }; - + const handleClose = () => { + setOpen(false); + size !== "large" ? setTimeout(() => { + if (widgetRef.current) + widgetRef.current.style.display = "none" + }, 250) + : + widgetRef.current && (widgetRef.current.style.display = "none") + }; + const handleOpen = () => { + setOpen(true); + if (widgetRef.current) + widgetRef.current.style.display = 'block' + } const dimensions = typeof size === 'object' && 'custom' in size ? sizesConfig.getCustom(size.custom) : sizesConfig[size]; + return ( {open && size === 'large' && - { - setOpen(false) - }} /> + } - setOpen(!open)} hidden={open}> - + - - {open && + + {
- setOpen(false)}> +
diff --git a/extensions/react-widget/src/types/index.ts b/extensions/react-widget/src/types/index.ts index 0a57a960..717efd92 100644 --- a/extensions/react-widget/src/types/index.ts +++ b/extensions/react-widget/src/types/index.ts @@ -29,6 +29,7 @@ export interface WidgetProps { }; theme?:THEME, buttonIcon?:string; + buttonText?:string; buttonBg?:string; collectFeedback?:boolean; deafultOpen?: boolean;