1- import React , { useState , useRef } from 'react' ;
1+ import React , { useEffect , useState , useRef } from 'react' ;
22import { ArrowUp } from 'lucide-react' ;
33import { useLocation } from '@docusaurus/router' ;
4+ import { useWindowSize } from '@docusaurus/theme-common' ;
45import styles from '../styles.module.css' ;
56
67export default function ChatbotTrigger ( ) {
78 const [ value , setValue ] = useState ( '' ) ;
9+ const [ isStuck , setIsStuck ] = useState ( false ) ;
10+ const containerRef = useRef < HTMLDivElement > ( null ) ;
811 const textareaRef = useRef < HTMLTextAreaElement > ( null ) ;
12+ const windowSize = useWindowSize ( ) ;
913 const { pathname } = useLocation ( ) ;
1014
15+ useEffect ( ( ) => {
16+ if ( windowSize === 'mobile' ) {
17+ setIsStuck ( false ) ;
18+ return ;
19+ }
20+
21+ const updateStuckState = ( ) => {
22+ const element = containerRef . current ;
23+ if ( ! element ) return ;
24+
25+ const rect = element . getBoundingClientRect ( ) ;
26+ const stickyBottom = Number . parseFloat ( getComputedStyle ( element ) . bottom ) || 0 ;
27+ const viewportBottom = window . innerHeight ;
28+ const targetBottom = viewportBottom - stickyBottom ;
29+
30+ setIsStuck ( Math . abs ( rect . bottom - targetBottom ) < 1.5 ) ;
31+ } ;
32+
33+ updateStuckState ( ) ;
34+ window . addEventListener ( 'scroll' , updateStuckState , { passive : true } ) ;
35+ window . addEventListener ( 'resize' , updateStuckState ) ;
36+
37+ return ( ) => {
38+ window . removeEventListener ( 'scroll' , updateStuckState ) ;
39+ window . removeEventListener ( 'resize' , updateStuckState ) ;
40+ } ;
41+ } , [ windowSize ] ) ;
42+
1143 const getPageMdUrl = ( ) => {
1244 const clean = pathname . replace ( / \/ $ / , '' ) ;
1345 return `${ clean } .md` ;
@@ -30,17 +62,25 @@ export default function ChatbotTrigger() {
3062 }
3163 } ;
3264
33- return (
34- < div className = { styles . chatbotTrigger } >
65+ if ( windowSize === 'mobile' ) {
66+ return null ;
67+ }
68+
69+ return < >
70+ < hr />
71+ < div
72+ ref = { containerRef }
73+ className = { `${ styles . chatbotTrigger } ${ isStuck ? styles . chatbotTriggerStuck : '' } ` }
74+ >
3575 < textarea
3676 ref = { textareaRef }
3777 className = { styles . chatbotTriggerTextarea }
38- placeholder = "Ask a question ..."
78+ placeholder = "Talk with this document ..."
3979 value = { value }
4080 onChange = { ( e ) => setValue ( e . target . value ) }
4181 onKeyDown = { handleKeyDown }
4282 rows = { 2 }
43- aria-label = "Ask the AI assistant "
83+ aria-label = "Talk with this document "
4484 />
4585 < div className = { styles . chatbotTriggerActions } >
4686 < button
@@ -55,5 +95,5 @@ export default function ChatbotTrigger() {
5595 </ button >
5696 </ div >
5797 </ div >
58- ) ;
98+ </ > ;
5999}
0 commit comments