1
+ /* eslint-disable react/prop-types */
1
2
import React , { useState , useEffect } from 'react' ;
2
3
import { useSelector } from 'react-redux' ;
3
4
import { useTranslation } from 'react-i18next' ;
@@ -8,6 +9,8 @@ import selectors from 'selectors';
8
9
9
10
import './AnnotationContentOverlay.scss' ;
10
11
12
+ import CustomElement from '../CustomElement' ;
13
+
11
14
const MAX_CHARACTERS = 100 ;
12
15
13
16
const AnnotationContentOverlay = ( ) => {
@@ -21,6 +24,13 @@ const AnnotationContentOverlay = () => {
21
24
top : 0 ,
22
25
} ) ;
23
26
27
+ // Clients have the option to customize how the tooltip is rendered
28
+ // by passing a handler
29
+ const customHandler = useSelector ( state =>
30
+ selectors . getAnnotationContentOverlayHandler ( state ) ,
31
+ ) ;
32
+ const isUsingCustomHandler = customHandler !== null ;
33
+
24
34
useEffect ( ( ) => {
25
35
const onMouseHover = e => {
26
36
const viewElement = core . getViewerElement ( ) ;
@@ -55,25 +65,58 @@ const AnnotationContentOverlay = () => {
55
65
const contents = annotation ?. getContents ( ) ;
56
66
const numberOfReplies = annotation ?. getReplies ( ) . length ;
57
67
58
- return isDisabled || isMobileDevice || ! contents ? null : (
68
+ const OverlayWrapper = props => (
59
69
< div
60
70
className = "Overlay AnnotationContentOverlay"
61
71
data-element = "annotationContentOverlay"
62
72
style = { { ...overlayPosition } }
63
73
>
64
- < div className = "author" > { core . getDisplayAuthor ( annotation ) } </ div >
65
- < div className = "contents" >
66
- { contents . length > MAX_CHARACTERS
67
- ? `${ contents . slice ( 0 , MAX_CHARACTERS ) } ...`
68
- : contents }
69
- </ div >
70
- { numberOfReplies > 0 && (
71
- < div className = "replies" >
72
- { t ( 'message.annotationReplyCount' , { count : numberOfReplies } ) }
73
- </ div >
74
- ) }
74
+ { props . children }
75
75
</ div >
76
76
) ;
77
+
78
+ const CustomOverlay = ( ) => {
79
+ if ( annotation ) {
80
+ return (
81
+ < OverlayWrapper >
82
+ < CustomElement render = { ( ) => customHandler ( annotation ) } />
83
+ </ OverlayWrapper >
84
+ ) ;
85
+ } else {
86
+ return null ;
87
+ }
88
+ } ;
89
+
90
+ const DefaultOverlay = ( ) => {
91
+ if ( contents ) {
92
+ return (
93
+ < OverlayWrapper >
94
+ < div className = "author" > { core . getDisplayAuthor ( annotation ) } </ div >
95
+ < div className = "contents" >
96
+ { contents . length > MAX_CHARACTERS
97
+ ? `${ contents . slice ( 0 , MAX_CHARACTERS ) } ...`
98
+ : contents }
99
+ </ div >
100
+ { numberOfReplies > 0 && (
101
+ < div className = "replies" >
102
+ { t ( 'message.annotationReplyCount' , { count : numberOfReplies } ) }
103
+ </ div >
104
+ ) }
105
+ </ OverlayWrapper >
106
+ ) ;
107
+ } else {
108
+ return null ;
109
+ }
110
+ } ;
111
+
112
+ if ( isDisabled || isMobileDevice ) {
113
+ return null ;
114
+ } else if ( isUsingCustomHandler ) {
115
+ return < CustomOverlay /> ;
116
+ } else {
117
+ return < DefaultOverlay /> ;
118
+ }
119
+
77
120
} ;
78
121
79
122
export default AnnotationContentOverlay ;
0 commit comments