@rzymek/react-pdf-highlighter 8.0.1-rc.0
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.
- package/LICENSE +21 -0
- package/README.md +43 -0
- package/dist/components/AreaHighlight.d.ts +8 -0
- package/dist/components/Highlight.d.ts +17 -0
- package/dist/components/HighlightLayer.d.ts +26 -0
- package/dist/components/MouseMonitor.d.ts +15 -0
- package/dist/components/MouseSelection.d.ts +10 -0
- package/dist/components/PdfHighlighter.d.ts +92 -0
- package/dist/components/PdfLoader.d.ts +32 -0
- package/dist/components/Popup.d.ts +8 -0
- package/dist/components/Tip.d.ts +20 -0
- package/dist/components/TipContainer.d.ts +13 -0
- package/dist/index.d.ts +7 -0
- package/dist/lib/coordinates.d.ts +8 -0
- package/dist/lib/get-area-as-png.d.ts +2 -0
- package/dist/lib/get-bounding-rect.d.ts +2 -0
- package/dist/lib/get-client-rects.d.ts +2 -0
- package/dist/lib/optimize-client-rects.d.ts +2 -0
- package/dist/lib/pdfjs-dom.d.ts +8 -0
- package/dist/node_modules/.pnpm/pdfjs-dist@4.4.168/node_modules/pdfjs-dist/web/pdf_viewer.js +8022 -0
- package/dist/node_modules/.pnpm/ts-debounce@4.0.0/node_modules/ts-debounce/dist/src/index.esm.js +38 -0
- package/dist/src/components/AreaHighlight.js +58 -0
- package/dist/src/components/Highlight.js +45 -0
- package/dist/src/components/HighlightLayer.js +47 -0
- package/dist/src/components/MouseMonitor.js +45 -0
- package/dist/src/components/MouseSelection.js +119 -0
- package/dist/src/components/PdfHighlighter.js +543 -0
- package/dist/src/components/PdfLoader.js +81 -0
- package/dist/src/components/Popup.js +42 -0
- package/dist/src/components/Tip.js +82 -0
- package/dist/src/components/TipContainer.js +62 -0
- package/dist/src/index.js +15 -0
- package/dist/src/lib/coordinates.js +50 -0
- package/dist/src/lib/get-area-as-png.js +31 -0
- package/dist/src/lib/get-bounding-rect.js +40 -0
- package/dist/src/lib/get-client-rects.js +39 -0
- package/dist/src/lib/optimize-client-rects.js +54 -0
- package/dist/src/lib/pdfjs-dom.js +64 -0
- package/dist/src/style/AreaHighlight.module.css.js +14 -0
- package/dist/src/style/Highlight.module.css.js +20 -0
- package/dist/src/style/MouseSelection.module.css.js +8 -0
- package/dist/src/style/PdfHighlighter.module.css.js +14 -0
- package/dist/src/style/Tip.module.css.js +11 -0
- package/dist/src/style/TipContainer.module.css.js +8 -0
- package/dist/style.css +2903 -0
- package/dist/types.d.ts +62 -0
- package/package.json +69 -0
package/dist/node_modules/.pnpm/ts-debounce@4.0.0/node_modules/ts-debounce/dist/src/index.esm.js
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
function r(r2, e, n) {
|
|
2
|
+
var i, t, o;
|
|
3
|
+
void 0 === n && (n = {});
|
|
4
|
+
var a = null != (i = n.isImmediate) && i, u = null != (t = n.callback) && t, c = n.maxWait, v = Date.now(), l = [];
|
|
5
|
+
function f() {
|
|
6
|
+
if (void 0 !== c) {
|
|
7
|
+
var r3 = Date.now() - v;
|
|
8
|
+
if (r3 + e >= c) return c - r3;
|
|
9
|
+
}
|
|
10
|
+
return e;
|
|
11
|
+
}
|
|
12
|
+
var d = function() {
|
|
13
|
+
var e2 = [].slice.call(arguments), n2 = this;
|
|
14
|
+
return new Promise(function(i2, t2) {
|
|
15
|
+
var c2 = a && void 0 === o;
|
|
16
|
+
if (void 0 !== o && clearTimeout(o), o = setTimeout(function() {
|
|
17
|
+
if (o = void 0, v = Date.now(), !a) {
|
|
18
|
+
var i3 = r2.apply(n2, e2);
|
|
19
|
+
u && u(i3), l.forEach(function(r3) {
|
|
20
|
+
return (0, r3.resolve)(i3);
|
|
21
|
+
}), l = [];
|
|
22
|
+
}
|
|
23
|
+
}, f()), c2) {
|
|
24
|
+
var d2 = r2.apply(n2, e2);
|
|
25
|
+
return u && u(d2), i2(d2);
|
|
26
|
+
}
|
|
27
|
+
l.push({ resolve: i2, reject: t2 });
|
|
28
|
+
});
|
|
29
|
+
};
|
|
30
|
+
return d.cancel = function(r3) {
|
|
31
|
+
void 0 !== o && clearTimeout(o), l.forEach(function(e2) {
|
|
32
|
+
return (0, e2.reject)(r3);
|
|
33
|
+
}), l = [];
|
|
34
|
+
}, d;
|
|
35
|
+
}
|
|
36
|
+
export {
|
|
37
|
+
r as debounce
|
|
38
|
+
};
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { jsx } from "react/jsx-runtime";
|
|
2
|
+
import { Rnd } from "react-rnd";
|
|
3
|
+
import { getPageFromElement } from "../lib/pdfjs-dom.js";
|
|
4
|
+
import styles from "../style/AreaHighlight.module.css.js";
|
|
5
|
+
function AreaHighlight({
|
|
6
|
+
highlight,
|
|
7
|
+
onChange,
|
|
8
|
+
isScrolledTo,
|
|
9
|
+
...otherProps
|
|
10
|
+
}) {
|
|
11
|
+
return /* @__PURE__ */ jsx(
|
|
12
|
+
"div",
|
|
13
|
+
{
|
|
14
|
+
className: `${styles.areaHighlight} ${isScrolledTo ? styles.scrolledTo : ""}`,
|
|
15
|
+
children: /* @__PURE__ */ jsx(
|
|
16
|
+
Rnd,
|
|
17
|
+
{
|
|
18
|
+
className: styles.part,
|
|
19
|
+
onDragStop: (_, data) => {
|
|
20
|
+
const boundingRect = {
|
|
21
|
+
...highlight.position.boundingRect,
|
|
22
|
+
top: data.y,
|
|
23
|
+
left: data.x
|
|
24
|
+
};
|
|
25
|
+
onChange(boundingRect);
|
|
26
|
+
},
|
|
27
|
+
onResizeStop: (_mouseEvent, _direction, ref, _delta, position) => {
|
|
28
|
+
var _a;
|
|
29
|
+
const boundingRect = {
|
|
30
|
+
top: position.y,
|
|
31
|
+
left: position.x,
|
|
32
|
+
width: ref.offsetWidth,
|
|
33
|
+
height: ref.offsetHeight,
|
|
34
|
+
pageNumber: ((_a = getPageFromElement(ref)) == null ? void 0 : _a.number) || -1
|
|
35
|
+
};
|
|
36
|
+
onChange(boundingRect);
|
|
37
|
+
},
|
|
38
|
+
position: {
|
|
39
|
+
x: highlight.position.boundingRect.left,
|
|
40
|
+
y: highlight.position.boundingRect.top
|
|
41
|
+
},
|
|
42
|
+
size: {
|
|
43
|
+
width: highlight.position.boundingRect.width,
|
|
44
|
+
height: highlight.position.boundingRect.height
|
|
45
|
+
},
|
|
46
|
+
onClick: (event) => {
|
|
47
|
+
event.stopPropagation();
|
|
48
|
+
event.preventDefault();
|
|
49
|
+
},
|
|
50
|
+
...otherProps
|
|
51
|
+
}
|
|
52
|
+
)
|
|
53
|
+
}
|
|
54
|
+
);
|
|
55
|
+
}
|
|
56
|
+
export {
|
|
57
|
+
AreaHighlight
|
|
58
|
+
};
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { jsxs, jsx } from "react/jsx-runtime";
|
|
2
|
+
import styles from "../style/Highlight.module.css.js";
|
|
3
|
+
function Highlight({
|
|
4
|
+
position,
|
|
5
|
+
onClick,
|
|
6
|
+
onMouseOver,
|
|
7
|
+
onMouseOut,
|
|
8
|
+
comment,
|
|
9
|
+
isScrolledTo
|
|
10
|
+
}) {
|
|
11
|
+
const { rects, boundingRect } = position;
|
|
12
|
+
return /* @__PURE__ */ jsxs(
|
|
13
|
+
"div",
|
|
14
|
+
{
|
|
15
|
+
className: `Highlight ${styles.highlight} ${isScrolledTo ? styles.scrolledTo : ""}`,
|
|
16
|
+
children: [
|
|
17
|
+
comment ? /* @__PURE__ */ jsx(
|
|
18
|
+
"div",
|
|
19
|
+
{
|
|
20
|
+
className: `Highlight__emoji ${styles.emoji}`,
|
|
21
|
+
style: {
|
|
22
|
+
left: 20,
|
|
23
|
+
top: boundingRect.top
|
|
24
|
+
},
|
|
25
|
+
children: comment.emoji
|
|
26
|
+
}
|
|
27
|
+
) : null,
|
|
28
|
+
/* @__PURE__ */ jsx("div", { className: `Highlight__parts ${styles.parts}`, children: rects.map((rect, index) => /* @__PURE__ */ jsx(
|
|
29
|
+
"div",
|
|
30
|
+
{
|
|
31
|
+
onMouseOver,
|
|
32
|
+
onMouseOut,
|
|
33
|
+
onClick,
|
|
34
|
+
style: rect,
|
|
35
|
+
className: `Highlight__part ${styles.part}`
|
|
36
|
+
},
|
|
37
|
+
index
|
|
38
|
+
)) })
|
|
39
|
+
]
|
|
40
|
+
}
|
|
41
|
+
);
|
|
42
|
+
}
|
|
43
|
+
export {
|
|
44
|
+
Highlight
|
|
45
|
+
};
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { jsx } from "react/jsx-runtime";
|
|
2
|
+
import { viewportToScaled } from "../lib/coordinates.js";
|
|
3
|
+
function HighlightLayer({
|
|
4
|
+
highlightsByPage,
|
|
5
|
+
scaledPositionToViewport,
|
|
6
|
+
pageNumber,
|
|
7
|
+
scrolledToHighlightId,
|
|
8
|
+
highlightTransform,
|
|
9
|
+
tip,
|
|
10
|
+
hideTipAndSelection,
|
|
11
|
+
viewer,
|
|
12
|
+
screenshot,
|
|
13
|
+
showTip,
|
|
14
|
+
setTip
|
|
15
|
+
}) {
|
|
16
|
+
const currentHighlights = highlightsByPage[String(pageNumber)] || [];
|
|
17
|
+
return /* @__PURE__ */ jsx("div", { children: viewer && currentHighlights.map((highlight, index) => {
|
|
18
|
+
const viewportHighlight = {
|
|
19
|
+
...highlight,
|
|
20
|
+
position: scaledPositionToViewport(highlight.position)
|
|
21
|
+
};
|
|
22
|
+
if (tip && tip.highlight.id === String(highlight.id)) {
|
|
23
|
+
showTip(tip.highlight, tip.callback(viewportHighlight));
|
|
24
|
+
}
|
|
25
|
+
const isScrolledTo = Boolean(scrolledToHighlightId === highlight.id);
|
|
26
|
+
return highlightTransform(
|
|
27
|
+
viewportHighlight,
|
|
28
|
+
index,
|
|
29
|
+
(highlight2, callback) => {
|
|
30
|
+
setTip({ highlight: highlight2, callback });
|
|
31
|
+
showTip(highlight2, callback(highlight2));
|
|
32
|
+
},
|
|
33
|
+
hideTipAndSelection,
|
|
34
|
+
(rect) => {
|
|
35
|
+
const viewport = viewer.getPageView(
|
|
36
|
+
(rect.pageNumber || Number.parseInt(pageNumber)) - 1
|
|
37
|
+
).viewport;
|
|
38
|
+
return viewportToScaled(rect, viewport);
|
|
39
|
+
},
|
|
40
|
+
(boundingRect) => screenshot(boundingRect, Number.parseInt(pageNumber)),
|
|
41
|
+
isScrolledTo
|
|
42
|
+
);
|
|
43
|
+
}) });
|
|
44
|
+
}
|
|
45
|
+
export {
|
|
46
|
+
HighlightLayer
|
|
47
|
+
};
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
3
|
+
var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
4
|
+
import { jsx } from "react/jsx-runtime";
|
|
5
|
+
import React, { Component } from "react";
|
|
6
|
+
class MouseMonitor extends Component {
|
|
7
|
+
constructor() {
|
|
8
|
+
super(...arguments);
|
|
9
|
+
__publicField(this, "container", null);
|
|
10
|
+
__publicField(this, "unsubscribe", () => {
|
|
11
|
+
});
|
|
12
|
+
__publicField(this, "onMouseMove", (event) => {
|
|
13
|
+
if (!this.container) {
|
|
14
|
+
return;
|
|
15
|
+
}
|
|
16
|
+
const { onMoveAway, paddingX, paddingY } = this.props;
|
|
17
|
+
const { clientX, clientY } = event;
|
|
18
|
+
const { left, top, width, height } = this.container.getBoundingClientRect();
|
|
19
|
+
const inBoundsX = clientX > left - paddingX && clientX < left + width + paddingX;
|
|
20
|
+
const inBoundsY = clientY > top - paddingY && clientY < top + height + paddingY;
|
|
21
|
+
const isNear = inBoundsX && inBoundsY;
|
|
22
|
+
if (!isNear) {
|
|
23
|
+
onMoveAway();
|
|
24
|
+
}
|
|
25
|
+
});
|
|
26
|
+
__publicField(this, "attachRef", (ref) => {
|
|
27
|
+
this.container = ref;
|
|
28
|
+
this.unsubscribe();
|
|
29
|
+
if (ref) {
|
|
30
|
+
const { ownerDocument: doc } = ref;
|
|
31
|
+
doc.addEventListener("mousemove", this.onMouseMove);
|
|
32
|
+
this.unsubscribe = () => {
|
|
33
|
+
doc.removeEventListener("mousemove", this.onMouseMove);
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
render() {
|
|
39
|
+
const { onMoveAway, paddingX, paddingY, children, ...restProps } = this.props;
|
|
40
|
+
return /* @__PURE__ */ jsx("div", { ref: this.attachRef, children: React.cloneElement(children, restProps) });
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
export {
|
|
44
|
+
MouseMonitor
|
|
45
|
+
};
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import { jsx } from "react/jsx-runtime";
|
|
2
|
+
import { useState, useRef, useEffect, useCallback } from "react";
|
|
3
|
+
import { isHTMLElement } from "../lib/pdfjs-dom.js";
|
|
4
|
+
import styles from "../style/MouseSelection.module.css.js";
|
|
5
|
+
const getBoundingRect = (start, end) => ({
|
|
6
|
+
left: Math.min(end.x, start.x),
|
|
7
|
+
top: Math.min(end.y, start.y),
|
|
8
|
+
width: Math.abs(end.x - start.x),
|
|
9
|
+
height: Math.abs(end.y - start.y)
|
|
10
|
+
});
|
|
11
|
+
const shouldRender = (boundingRect) => boundingRect.width >= 1 && boundingRect.height >= 1;
|
|
12
|
+
function MouseSelection({
|
|
13
|
+
onSelection,
|
|
14
|
+
onDragStart,
|
|
15
|
+
onDragEnd,
|
|
16
|
+
shouldStart,
|
|
17
|
+
onChange
|
|
18
|
+
}) {
|
|
19
|
+
const [locked, setLocked] = useState(false);
|
|
20
|
+
const [start, setStart] = useState(null);
|
|
21
|
+
const [end, setEnd] = useState(null);
|
|
22
|
+
const rootRef = useRef(null);
|
|
23
|
+
const startRef = useRef(start);
|
|
24
|
+
const lockedRef = useRef(locked);
|
|
25
|
+
useEffect(() => {
|
|
26
|
+
startRef.current = start;
|
|
27
|
+
}, [start]);
|
|
28
|
+
useEffect(() => {
|
|
29
|
+
lockedRef.current = locked;
|
|
30
|
+
}, [locked]);
|
|
31
|
+
const reset = useCallback(() => {
|
|
32
|
+
onDragEnd();
|
|
33
|
+
setStart(null);
|
|
34
|
+
setEnd(null);
|
|
35
|
+
setLocked(false);
|
|
36
|
+
}, [onDragEnd]);
|
|
37
|
+
useEffect(() => {
|
|
38
|
+
const isVisible = Boolean(start && end);
|
|
39
|
+
onChange(isVisible);
|
|
40
|
+
}, [start, end, onChange]);
|
|
41
|
+
useEffect(() => {
|
|
42
|
+
const root = rootRef.current;
|
|
43
|
+
if (!root) {
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
const container = root.parentElement;
|
|
47
|
+
if (!container || !isHTMLElement(container)) {
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
const containerCoords = (pageX, pageY) => {
|
|
51
|
+
const containerBoundingRect = container.getBoundingClientRect();
|
|
52
|
+
return {
|
|
53
|
+
x: pageX - containerBoundingRect.left + container.scrollLeft,
|
|
54
|
+
y: pageY - containerBoundingRect.top + container.scrollTop - window.scrollY
|
|
55
|
+
};
|
|
56
|
+
};
|
|
57
|
+
const mouseMoveHandler = (event) => {
|
|
58
|
+
if (!startRef.current || lockedRef.current) {
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
setEnd(containerCoords(event.pageX, event.pageY));
|
|
62
|
+
};
|
|
63
|
+
const mouseDownHandler = (event) => {
|
|
64
|
+
if (!shouldStart(event)) {
|
|
65
|
+
reset();
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
const startTarget = event.target;
|
|
69
|
+
if (!(startTarget instanceof Element) || !isHTMLElement(startTarget)) {
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
onDragStart();
|
|
73
|
+
setStart(containerCoords(event.pageX, event.pageY));
|
|
74
|
+
setEnd(null);
|
|
75
|
+
setLocked(false);
|
|
76
|
+
const mouseUpHandler = (event2) => {
|
|
77
|
+
var _a;
|
|
78
|
+
(_a = event2.currentTarget) == null ? void 0 : _a.removeEventListener("mouseup", mouseUpHandler);
|
|
79
|
+
const currentStart = startRef.current;
|
|
80
|
+
if (!currentStart) {
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
if (!(event2 instanceof MouseEvent)) {
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
const endCoords = containerCoords(event2.pageX, event2.pageY);
|
|
87
|
+
const boundingRect = getBoundingRect(currentStart, endCoords);
|
|
88
|
+
if (!(event2.target instanceof Element) || !isHTMLElement(event2.target) || !container.contains(event2.target) || !shouldRender(boundingRect)) {
|
|
89
|
+
reset();
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
setEnd(endCoords);
|
|
93
|
+
setLocked(true);
|
|
94
|
+
onSelection(startTarget, boundingRect, reset);
|
|
95
|
+
onDragEnd();
|
|
96
|
+
};
|
|
97
|
+
const doc = container.ownerDocument;
|
|
98
|
+
if (doc == null ? void 0 : doc.body) {
|
|
99
|
+
doc.body.addEventListener("mouseup", mouseUpHandler);
|
|
100
|
+
}
|
|
101
|
+
};
|
|
102
|
+
container.addEventListener("mousemove", mouseMoveHandler);
|
|
103
|
+
container.addEventListener("mousedown", mouseDownHandler);
|
|
104
|
+
return () => {
|
|
105
|
+
container.removeEventListener("mousemove", mouseMoveHandler);
|
|
106
|
+
container.removeEventListener("mousedown", mouseDownHandler);
|
|
107
|
+
};
|
|
108
|
+
}, [shouldStart, onDragStart, onDragEnd, onSelection, reset]);
|
|
109
|
+
return /* @__PURE__ */ jsx("div", { ref: rootRef, children: start && end && /* @__PURE__ */ jsx(
|
|
110
|
+
"div",
|
|
111
|
+
{
|
|
112
|
+
className: styles.mouseSelection,
|
|
113
|
+
style: getBoundingRect(start, end)
|
|
114
|
+
}
|
|
115
|
+
) });
|
|
116
|
+
}
|
|
117
|
+
export {
|
|
118
|
+
MouseSelection
|
|
119
|
+
};
|