@anaralabs/lector 3.5.3 → 3.5.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -40,7 +40,7 @@ declare interface Annotation {
40
40
  export { Annotation }
41
41
  export { Annotation as Annotation_alias_1 }
42
42
 
43
- export declare const AnnotationHighlightLayer: ({ className, style, renderTooltipContent, tooltipClassName, focusedAnnotationId, onAnnotationClick, }: AnnotationHighlightLayerProps) => JSX.Element;
43
+ export declare const AnnotationHighlightLayer: ({ className, style, renderTooltipContent, renderHoverTooltipContent, tooltipClassName, focusedAnnotationId, onAnnotationClick, hoverTooltipClassName }: AnnotationHighlightLayerProps) => JSX.Element;
44
44
 
45
45
  declare interface AnnotationHighlightLayerProps {
46
46
  className?: string;
@@ -49,9 +49,14 @@ declare interface AnnotationHighlightLayerProps {
49
49
  annotation: Annotation;
50
50
  onClose: () => void;
51
51
  }) => React.ReactNode;
52
+ renderHoverTooltipContent: (props: {
53
+ annotation: Annotation;
54
+ onClose: () => void;
55
+ }) => React.ReactNode;
52
56
  focusedAnnotationId?: string;
53
57
  onAnnotationClick?: (annotation: Annotation) => void;
54
58
  tooltipClassName?: string;
59
+ hoverTooltipClassName?: string;
55
60
  }
56
61
 
57
62
  /**
@@ -91,15 +96,21 @@ declare interface AnnotationState {
91
96
  setAnnotations: (annotations: Annotation[]) => void;
92
97
  }
93
98
 
94
- export declare const AnnotationTooltip: ({ annotation, children, tooltipContent, onOpenChange, className, isOpen: controlledIsOpen, }: AnnotationTooltipProps) => JSX.Element;
99
+ export declare const AnnotationTooltip: ({ annotation, children, tooltipContent, hoverTooltipContent, onOpenChange, className, hoverClassName, isOpen: controlledIsOpen, }: AnnotationTooltipProps) => JSX.Element;
95
100
 
96
101
  declare interface AnnotationTooltipProps {
97
102
  annotation: Annotation;
98
103
  children: React.ReactNode;
99
104
  tooltipContent: React.ReactNode;
105
+ hoverTooltipContent?: React.ReactNode;
100
106
  onOpenChange?: (open: boolean) => void;
101
107
  isOpen?: boolean;
102
108
  className?: string;
109
+ hoverClassName?: string;
110
+ renderHoverTooltipContent?: (props: {
111
+ annotation: Annotation;
112
+ onClose: () => void;
113
+ }) => React.ReactNode;
103
114
  }
104
115
 
105
116
  /**
package/dist/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  'use client';
2
2
 
3
- import React, { createContext, forwardRef, useCallback, useContext, useState, useRef, useEffect, cloneElement, createRef, useLayoutEffect } from 'react';
3
+ import React, { createContext, forwardRef, useRef, useCallback, useContext, useState, useEffect, cloneElement, createRef, useLayoutEffect } from 'react';
4
4
  import { createPortal } from 'react-dom';
5
5
  import { useFloating, autoUpdate, offset, shift, useDismiss, useInteractions, inline, flip } from '@floating-ui/react';
6
6
  import { useVirtualizer, elementScroll, debounce } from '@tanstack/react-virtual';
@@ -261,11 +261,15 @@ var AnnotationTooltip = ({
261
261
  annotation,
262
262
  children,
263
263
  tooltipContent,
264
+ hoverTooltipContent,
264
265
  onOpenChange,
265
266
  className,
267
+ hoverClassName,
266
268
  isOpen: controlledIsOpen
267
269
  }) => {
268
270
  const viewportRef = usePdf((state) => state.viewportRef);
271
+ const closeTimeoutRef = useRef(null);
272
+ const isMouseInTooltipRef = useRef(false);
269
273
  const {
270
274
  isOpen: uncontrolledIsOpen,
271
275
  setIsOpen,
@@ -277,19 +281,64 @@ var AnnotationTooltip = ({
277
281
  annotation,
278
282
  onOpenChange
279
283
  });
284
+ const {
285
+ isOpen: hoverIsOpen,
286
+ setIsOpen: setHoverIsOpen,
287
+ refs: hoverRefs,
288
+ floatingStyles: hoverFloatingStyles,
289
+ getFloatingProps: getHoverFloatingProps,
290
+ getReferenceProps: getHoverReferenceProps
291
+ } = useAnnotationTooltip({
292
+ annotation
293
+ });
280
294
  const isOpen = controlledIsOpen ?? uncontrolledIsOpen;
281
295
  const handleClick = useCallback(() => {
282
296
  if (controlledIsOpen === void 0) {
283
297
  setIsOpen(!isOpen);
284
298
  }
285
299
  }, [controlledIsOpen, isOpen, setIsOpen]);
300
+ const handleMouseEnter = useCallback(() => {
301
+ if (hoverTooltipContent) {
302
+ if (closeTimeoutRef.current) {
303
+ clearTimeout(closeTimeoutRef.current);
304
+ closeTimeoutRef.current = null;
305
+ }
306
+ setHoverIsOpen(true);
307
+ }
308
+ }, [hoverTooltipContent, setHoverIsOpen]);
309
+ const closeTooltip = useCallback(() => {
310
+ if (!isMouseInTooltipRef.current) {
311
+ setHoverIsOpen(false);
312
+ }
313
+ }, [setHoverIsOpen]);
314
+ const handleMouseLeave = useCallback(() => {
315
+ if (!hoverTooltipContent) return;
316
+ closeTimeoutRef.current = setTimeout(closeTooltip, 100);
317
+ }, [hoverTooltipContent, closeTooltip]);
318
+ const handleTooltipMouseEnter = useCallback(() => {
319
+ isMouseInTooltipRef.current = true;
320
+ if (closeTimeoutRef.current) {
321
+ clearTimeout(closeTimeoutRef.current);
322
+ closeTimeoutRef.current = null;
323
+ }
324
+ }, []);
325
+ const handleTooltipMouseLeave = useCallback(() => {
326
+ isMouseInTooltipRef.current = false;
327
+ setHoverIsOpen(false);
328
+ }, [setHoverIsOpen]);
286
329
  return /* @__PURE__ */ jsxs(Fragment, { children: [
287
330
  /* @__PURE__ */ jsx(
288
331
  "div",
289
332
  {
290
- ref: refs.setReference,
333
+ ref: (node) => {
334
+ refs.setReference(node);
335
+ hoverRefs.setReference(node);
336
+ },
291
337
  onClick: handleClick,
338
+ onMouseEnter: handleMouseEnter,
339
+ onMouseLeave: handleMouseLeave,
292
340
  ...getReferenceProps(),
341
+ ...getHoverReferenceProps(),
293
342
  children
294
343
  }
295
344
  ),
@@ -299,16 +348,39 @@ var AnnotationTooltip = ({
299
348
  {
300
349
  ref: refs.setFloating,
301
350
  className,
351
+ "data-annotation-tooltip": "click",
302
352
  style: {
303
353
  ...floatingStyles,
304
354
  position: "absolute",
305
- pointerEvents: "auto"
355
+ pointerEvents: "auto",
356
+ zIndex: 50
306
357
  },
307
358
  ...getFloatingProps(),
308
359
  children: tooltipContent
309
360
  }
310
361
  ),
311
362
  viewportRef.current
363
+ ),
364
+ !isOpen && hoverIsOpen && annotation.comment && hoverTooltipContent && viewportRef.current && createPortal(
365
+ /* @__PURE__ */ jsx(
366
+ "div",
367
+ {
368
+ ref: hoverRefs.setFloating,
369
+ className: hoverClassName,
370
+ "data-annotation-tooltip": "hover",
371
+ style: {
372
+ ...hoverFloatingStyles,
373
+ position: "absolute",
374
+ pointerEvents: "auto",
375
+ zIndex: 51
376
+ },
377
+ onMouseEnter: handleTooltipMouseEnter,
378
+ onMouseLeave: handleTooltipMouseLeave,
379
+ ...getHoverFloatingProps(),
380
+ children: hoverTooltipContent
381
+ }
382
+ ),
383
+ viewportRef.current
312
384
  )
313
385
  ] });
314
386
  };
@@ -341,9 +413,11 @@ var AnnotationHighlightLayer = ({
341
413
  className,
342
414
  style,
343
415
  renderTooltipContent,
416
+ renderHoverTooltipContent,
344
417
  tooltipClassName,
345
418
  focusedAnnotationId,
346
- onAnnotationClick
419
+ onAnnotationClick,
420
+ hoverTooltipClassName
347
421
  }) => {
348
422
  const { annotations } = useAnnotations();
349
423
  const pageNumber = usePDFPageNumber();
@@ -355,6 +429,7 @@ var AnnotationHighlightLayer = ({
355
429
  {
356
430
  annotation,
357
431
  className: tooltipClassName,
432
+ hoverClassName: hoverTooltipClassName,
358
433
  isOpen: focusedAnnotationId === annotation.id,
359
434
  onOpenChange: (open) => {
360
435
  if (open && onAnnotationClick) {
@@ -366,6 +441,11 @@ var AnnotationHighlightLayer = ({
366
441
  onClose: () => {
367
442
  }
368
443
  }),
444
+ hoverTooltipContent: renderHoverTooltipContent({
445
+ annotation,
446
+ onClose: () => {
447
+ }
448
+ }),
369
449
  children: /* @__PURE__ */ jsx(
370
450
  "div",
371
451
  {
@@ -1072,7 +1152,27 @@ var SelectionTooltip = ({ children }) => {
1072
1152
  const handleSelectionChange = () => {
1073
1153
  const selection = document.getSelection();
1074
1154
  if (selection && viewportRef.current?.contains(selection.anchorNode)) {
1075
- requestAnimationFrame(updateTooltipPosition);
1155
+ const anchorNode = selection.anchorNode;
1156
+ const focusNode = selection.focusNode;
1157
+ const isInUnselectableArea = (node) => {
1158
+ if (!node) return false;
1159
+ let element = node.nodeType === Node.ELEMENT_NODE ? node : node.parentElement;
1160
+ while (element) {
1161
+ if (element.getAttribute("data-annotation-tooltip")) {
1162
+ return true;
1163
+ }
1164
+ if (element.hasAttribute("data-floating-ui-portal")) {
1165
+ return true;
1166
+ }
1167
+ element = element.parentElement;
1168
+ }
1169
+ return false;
1170
+ };
1171
+ if (!isInUnselectableArea(anchorNode) && !isInUnselectableArea(focusNode)) {
1172
+ requestAnimationFrame(updateTooltipPosition);
1173
+ } else {
1174
+ setIsOpen(false);
1175
+ }
1076
1176
  } else {
1077
1177
  setIsOpen(false);
1078
1178
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@anaralabs/lector",
3
- "version": "3.5.3",
3
+ "version": "3.5.4",
4
4
  "description": "Headless PDF viewer for React",
5
5
  "author": "andrewdr (https://github.com/andrewdoro)",
6
6
  "license": "MIT",