11import { ReactNode , useEffect , useMemo , useRef , useState } from 'react' ;
22import { useAnnotator , useSelection } from '@annotorious/react' ;
3- import { isRevived , NOT_ANNOTATABLE_CLASS , TextAnnotation , TextAnnotator } from '@recogito/text-annotator' ;
3+ import {
4+ NOT_ANNOTATABLE_CLASS ,
5+ denormalizeRectWithOffset ,
6+ toDomRectList ,
7+ type TextAnnotation ,
8+ type TextAnnotator ,
9+ } from '@recogito/text-annotator' ;
10+
411import { isMobile } from './isMobile' ;
512import {
613 arrow ,
@@ -64,8 +71,8 @@ export const TextAnnotationPopup = (props: TextAnnotationPopupProps) => {
6471 shift ( { crossAxis : true , padding : 10 } )
6572 ] ;
6673
67- return props . arrow
68- ? [ ...m , arrow ( { element : arrowRef } ) ]
74+ return props . arrow
75+ ? [ ...m , arrow ( { element : arrowRef } ) ]
6976 : m ;
7077 } , [ props . arrow ] ) ;
7178
@@ -89,26 +96,37 @@ export const TextAnnotationPopup = (props: TextAnnotationPopupProps) => {
8996 const { getFloatingProps } = useInteractions ( [ dismiss , role ] ) ;
9097
9198 useEffect ( ( ) => {
92- const annotationSelector = annotation ?. target . selector ;
93- setOpen ( annotationSelector ?. length > 0 ? isRevived ( annotationSelector ) : false ) ;
94- } , [ annotation ] ) ;
99+ if ( annotation ?. id ) {
100+ const bounds = r ?. state . store . getAnnotationBounds ( annotation . id ) ;
101+ setOpen ( Boolean ( bounds ) ) ;
102+ } else {
103+ setOpen ( false ) ;
104+ }
105+ } , [ annotation ?. id , r ?. state . store ] ) ;
95106
96107 useEffect ( ( ) => {
97- if ( isOpen && annotation ) {
98- const {
99- target : {
100- selector : [ { range } ]
101- }
102- } = annotation ;
108+ if ( ! r ) return ;
103109
110+ if ( isOpen && annotation ?. id ) {
104111 refs . setPositionReference ( {
105- getBoundingClientRect : ( ) => range . getBoundingClientRect ( ) ,
106- getClientRects : ( ) => range . getClientRects ( )
112+ getBoundingClientRect : ( ) => {
113+ const bounds = r . state . store . getAnnotationBounds ( annotation . id ) ;
114+ return bounds
115+ ? denormalizeRectWithOffset ( bounds , r . element . getBoundingClientRect ( ) )
116+ : new DOMRect ( ) ;
117+ } ,
118+ getClientRects : ( ) => {
119+ const rects = r . state . store . getAnnotationRects ( annotation . id ) ;
120+ const denormalizedRects = rects . map ( ( rect ) =>
121+ denormalizeRectWithOffset ( rect , r . element . getBoundingClientRect ( ) )
122+ ) ;
123+ return toDomRectList ( denormalizedRects ) ;
124+ }
107125 } ) ;
108126 } else {
109127 refs . setPositionReference ( null ) ;
110128 }
111- } , [ isOpen , annotation , refs ] ) ;
129+ } , [ isOpen , annotation ?. id , annotation ?. target , r ] ) ;
112130
113131 useEffect ( ( ) => {
114132 const config : MutationObserverInit = { attributes : true , childList : true , subtree : true } ;
@@ -151,9 +169,9 @@ export const TextAnnotationPopup = (props: TextAnnotationPopupProps) => {
151169 } ) }
152170
153171 { props . arrow && (
154- < FloatingArrow
172+ < FloatingArrow
155173 ref = { arrowRef }
156- context = { context }
174+ context = { context }
157175 { ...( props . arrowProps || { } ) } />
158176 ) }
159177
0 commit comments