1- import React , { useEffect } from 'react' ;
1+ import React , { useEffect , useState , useRef } from 'react' ;
22import './index.scss' ;
33import { customizeDocContent , addScrollListener } from './helper' ;
44import Footer from '../Footer' ;
@@ -18,6 +18,52 @@ const Document = (props: {
1818 breadcrumsData : any ;
1919 markdownBody ?: string ;
2020} ) => {
21+ const [ selectionPos , setSelectionPos ] = useState < { top : number ; left : number } | null > ( null ) ;
22+ const selectionRef = useRef < string > ( '' ) ;
23+
24+ useEffect ( ( ) => {
25+ let mouseDownX = 0 ;
26+ let mouseDownY = 0 ;
27+
28+ const handleMouseUp = ( e : MouseEvent ) => {
29+ const target = e . target as HTMLElement ;
30+ if ( target . closest ( '.selection-cta-button' ) ) return ;
31+
32+ // If mouse didn't move (plain click, not a drag-select), don't re-show
33+ const moved = Math . abs ( e . clientX - mouseDownX ) > 3 || Math . abs ( e . clientY - mouseDownY ) > 3 ;
34+ if ( ! moved ) return ;
35+
36+ const selection = window . getSelection ( ) ;
37+ const text = selection ?. toString ( ) . trim ( ) || '' ;
38+ if ( ! text ) {
39+ setSelectionPos ( null ) ;
40+ return ;
41+ }
42+ const range = selection ! . getRangeAt ( 0 ) ;
43+ const rect = range . getBoundingClientRect ( ) ;
44+ selectionRef . current = text ;
45+ const HEADER_HEIGHT = 108 ; // main header (60) + secondary header (48)
46+ const rawTop = rect . top - 36 ;
47+ setSelectionPos ( {
48+ top : Math . max ( HEADER_HEIGHT + 4 , rawTop ) ,
49+ left : rect . left ,
50+ } ) ;
51+ } ;
52+
53+ const handleMouseDown = ( e : MouseEvent ) => {
54+ mouseDownX = e . clientX ;
55+ mouseDownY = e . clientY ;
56+ setSelectionPos ( null ) ;
57+ } ;
58+
59+ document . addEventListener ( 'mouseup' , handleMouseUp ) ;
60+ document . addEventListener ( 'mousedown' , handleMouseDown ) ;
61+ return ( ) => {
62+ document . removeEventListener ( 'mouseup' , handleMouseUp ) ;
63+ document . removeEventListener ( 'mousedown' , handleMouseDown ) ;
64+ } ;
65+ } , [ ] ) ;
66+
2167 useEffect ( ( ) => {
2268 customizeDocContent ( ) ;
2369 } , [ props . docContent ] ) ;
@@ -131,6 +177,17 @@ const Document = (props: {
131177 className = "documentWrapper"
132178 style = { ! props . shouldShowRightNav ? { width : '100%' } : undefined }
133179 >
180+ { selectionPos && (
181+ < a
182+ className = "selection-cta-button"
183+ href = "https://try.thoughtspot.com"
184+ target = "_blank"
185+ rel = "noopener noreferrer"
186+ style = { { top : selectionPos . top , left : selectionPos . left } }
187+ >
188+ Ask SpotterCode
189+ </ a >
190+ ) }
134191 { ! isHomePage && (
135192 < Breadcrums
136193 breadcrumsData = { props . breadcrumsData }
0 commit comments