diff --git a/src/apis/index.js b/src/apis/index.js index 940cc8d86..442ca049f 100644 --- a/src/apis/index.js +++ b/src/apis/index.js @@ -136,6 +136,7 @@ import selectThumbnailPages from './selectThumbnailPages'; import unselectThumbnailPages from './unselectThumbnailPages'; import setSearchResults from './setSearchResults'; import setActiveResult from './setActiveResult'; +import setAnnotationContentOverlayHandler from './setAnnotationContentOverlayHandler'; export default store => { window.readerControl = { @@ -217,6 +218,7 @@ export default store => { getSelectedThumbnailPageNumbers: getSelectedThumbnailPageNumbers(store), selectThumbnailPages: selectThumbnailPages(store), unselectThumbnailPages: unselectThumbnailPages(store), + setAnnotationContentOverlayHandler: setAnnotationContentOverlayHandler(store), // undocumented and deprecated, to be removed in 7.0 closeElement: closeElement(store), diff --git a/src/apis/setAnnotationContentOverlayHandler.js b/src/apis/setAnnotationContentOverlayHandler.js new file mode 100644 index 000000000..14edfba8c --- /dev/null +++ b/src/apis/setAnnotationContentOverlayHandler.js @@ -0,0 +1,22 @@ +import action from 'actions'; + +/** + * Adds a custom overlay to annotations on mouseHover, overriding the existing overlay. + * @method WebViewerInstance#setAnnotationContentOverlayHandler + * @param {function} customOverlayHandler a function that takes an annotation and returns a DOM Element, which is rendered as a tooltip when hovering over the annotation + * * @example +WebViewer(...) + .then(function(instance) { + instance.setAnnotationContentOverlayHandler(annotation => { + const div = document.createElement('div'); + div.appendChild(document.createTextNode(`Created by: ${annotation.Author}`)); + div.appendChild(document.createElement('br')); + div.appendChild(document.createTextNode(`Created on ${annotation.DateCreated}`)); + return div; + }); + }); + */ + +export default store => annotationContentOverlayHandler => { + store.dispatch(action.setAnnotationContentOverlayHandler(annotationContentOverlayHandler)); +}; \ No newline at end of file diff --git a/src/components/AnnotationContentOverlay/AnnotationContentOverlay.js b/src/components/AnnotationContentOverlay/AnnotationContentOverlay.js index 38a9bc814..c6db1b813 100644 --- a/src/components/AnnotationContentOverlay/AnnotationContentOverlay.js +++ b/src/components/AnnotationContentOverlay/AnnotationContentOverlay.js @@ -1,3 +1,4 @@ +/* eslint-disable react/prop-types */ import React, { useState, useEffect } from 'react'; import { useSelector } from 'react-redux'; import { useTranslation } from 'react-i18next'; @@ -8,6 +9,8 @@ import selectors from 'selectors'; import './AnnotationContentOverlay.scss'; +import CustomElement from '../CustomElement'; + const MAX_CHARACTERS = 100; const AnnotationContentOverlay = () => { @@ -21,6 +24,13 @@ const AnnotationContentOverlay = () => { top: 0, }); + // Clients have the option to customize how the tooltip is rendered + // by passing a handler + const customHandler = useSelector(state => + selectors.getAnnotationContentOverlayHandler(state), + ); + const isUsingCustomHandler = customHandler !== null; + useEffect(() => { const onMouseHover = e => { const viewElement = core.getViewerElement(); @@ -55,25 +65,58 @@ const AnnotationContentOverlay = () => { const contents = annotation?.getContents(); const numberOfReplies = annotation?.getReplies().length; - return isDisabled || isMobileDevice || !contents ? null : ( + const OverlayWrapper = props => (