react-pdf-highlighter-plus 1.0.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 +22 -0
- package/README.md +411 -0
- package/dist/esm/components/AreaHighlight.d.ts +82 -0
- package/dist/esm/components/AreaHighlight.js +109 -0
- package/dist/esm/components/AreaHighlight.js.map +1 -0
- package/dist/esm/components/DrawingCanvas.d.ts +48 -0
- package/dist/esm/components/DrawingCanvas.js +277 -0
- package/dist/esm/components/DrawingCanvas.js.map +1 -0
- package/dist/esm/components/DrawingHighlight.d.ts +70 -0
- package/dist/esm/components/DrawingHighlight.js +164 -0
- package/dist/esm/components/DrawingHighlight.js.map +1 -0
- package/dist/esm/components/FreetextHighlight.d.ts +112 -0
- package/dist/esm/components/FreetextHighlight.js +193 -0
- package/dist/esm/components/FreetextHighlight.js.map +1 -0
- package/dist/esm/components/HighlightLayer.d.ts +49 -0
- package/dist/esm/components/HighlightLayer.js +37 -0
- package/dist/esm/components/HighlightLayer.js.map +1 -0
- package/dist/esm/components/ImageHighlight.d.ts +63 -0
- package/dist/esm/components/ImageHighlight.js +65 -0
- package/dist/esm/components/ImageHighlight.js.map +1 -0
- package/dist/esm/components/MonitoredHighlightContainer.d.ts +37 -0
- package/dist/esm/components/MonitoredHighlightContainer.js +42 -0
- package/dist/esm/components/MonitoredHighlightContainer.js.map +1 -0
- package/dist/esm/components/MouseMonitor.d.ts +34 -0
- package/dist/esm/components/MouseMonitor.js +30 -0
- package/dist/esm/components/MouseMonitor.js.map +1 -0
- package/dist/esm/components/MouseSelection.d.ts +66 -0
- package/dist/esm/components/MouseSelection.js +122 -0
- package/dist/esm/components/MouseSelection.js.map +1 -0
- package/dist/esm/components/PdfHighlighter.d.ts +184 -0
- package/dist/esm/components/PdfHighlighter.js +410 -0
- package/dist/esm/components/PdfHighlighter.js.map +1 -0
- package/dist/esm/components/PdfLoader.d.ts +55 -0
- package/dist/esm/components/PdfLoader.js +57 -0
- package/dist/esm/components/PdfLoader.js.map +1 -0
- package/dist/esm/components/ShapeCanvas.d.ts +51 -0
- package/dist/esm/components/ShapeCanvas.js +205 -0
- package/dist/esm/components/ShapeCanvas.js.map +1 -0
- package/dist/esm/components/ShapeHighlight.d.ts +107 -0
- package/dist/esm/components/ShapeHighlight.js +140 -0
- package/dist/esm/components/ShapeHighlight.js.map +1 -0
- package/dist/esm/components/SignaturePad.d.ts +40 -0
- package/dist/esm/components/SignaturePad.js +138 -0
- package/dist/esm/components/SignaturePad.js.map +1 -0
- package/dist/esm/components/TextHighlight.d.ts +93 -0
- package/dist/esm/components/TextHighlight.js +115 -0
- package/dist/esm/components/TextHighlight.js.map +1 -0
- package/dist/esm/components/TipContainer.d.ts +27 -0
- package/dist/esm/components/TipContainer.js +58 -0
- package/dist/esm/components/TipContainer.js.map +1 -0
- package/dist/esm/contexts/HighlightContext.d.ts +44 -0
- package/dist/esm/contexts/HighlightContext.js +16 -0
- package/dist/esm/contexts/HighlightContext.js.map +1 -0
- package/dist/esm/contexts/PdfHighlighterContext.d.ts +89 -0
- package/dist/esm/contexts/PdfHighlighterContext.js +16 -0
- package/dist/esm/contexts/PdfHighlighterContext.js.map +1 -0
- package/dist/esm/index.d.ts +19 -0
- package/dist/esm/index.js +19 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/lib/coordinates.d.ts +16 -0
- package/dist/esm/lib/coordinates.js +69 -0
- package/dist/esm/lib/coordinates.js.map +1 -0
- package/dist/esm/lib/export-pdf.d.ts +81 -0
- package/dist/esm/lib/export-pdf.js +511 -0
- package/dist/esm/lib/export-pdf.js.map +1 -0
- package/dist/esm/lib/get-bounding-rect.d.ts +3 -0
- package/dist/esm/lib/get-bounding-rect.js +35 -0
- package/dist/esm/lib/get-bounding-rect.js.map +1 -0
- package/dist/esm/lib/get-client-rects.d.ts +3 -0
- package/dist/esm/lib/get-client-rects.js +43 -0
- package/dist/esm/lib/get-client-rects.js.map +1 -0
- package/dist/esm/lib/group-highlights-by-page.d.ts +6 -0
- package/dist/esm/lib/group-highlights-by-page.js +23 -0
- package/dist/esm/lib/group-highlights-by-page.js.map +1 -0
- package/dist/esm/lib/optimize-client-rects.d.ts +3 -0
- package/dist/esm/lib/optimize-client-rects.js +65 -0
- package/dist/esm/lib/optimize-client-rects.js.map +1 -0
- package/dist/esm/lib/pdfjs-dom.d.ts +9 -0
- package/dist/esm/lib/pdfjs-dom.js +55 -0
- package/dist/esm/lib/pdfjs-dom.js.map +1 -0
- package/dist/esm/lib/screenshot.d.ts +4 -0
- package/dist/esm/lib/screenshot.js +24 -0
- package/dist/esm/lib/screenshot.js.map +1 -0
- package/dist/esm/style/AreaHighlight.css +134 -0
- package/dist/esm/style/DrawingCanvas.css +62 -0
- package/dist/esm/style/DrawingHighlight.css +184 -0
- package/dist/esm/style/FreetextHighlight.css +249 -0
- package/dist/esm/style/ImageHighlight.css +97 -0
- package/dist/esm/style/MouseSelection.css +15 -0
- package/dist/esm/style/PdfHighlighter.css +77 -0
- package/dist/esm/style/ShapeCanvas.css +47 -0
- package/dist/esm/style/ShapeHighlight.css +182 -0
- package/dist/esm/style/SignaturePad.css +83 -0
- package/dist/esm/style/TextHighlight.css +199 -0
- package/dist/esm/style/pdf_viewer.css +41 -0
- package/dist/esm/types.d.ts +213 -0
- package/dist/esm/types.js +2 -0
- package/dist/esm/types.js.map +1 -0
- package/package.json +91 -0
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
import React, { useState, useRef, useEffect, } from "react";
|
|
2
|
+
import { Rnd } from "react-rnd";
|
|
3
|
+
import { getPageFromElement } from "../lib/pdfjs-dom";
|
|
4
|
+
import "../style/FreetextHighlight.css";
|
|
5
|
+
/**
|
|
6
|
+
* Renders a draggable, editable freetext annotation.
|
|
7
|
+
*
|
|
8
|
+
* @category Component
|
|
9
|
+
*/
|
|
10
|
+
// Default icons
|
|
11
|
+
const DefaultDragIcon = () => (React.createElement("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "currentColor" },
|
|
12
|
+
React.createElement("circle", { cx: "8", cy: "6", r: "2" }),
|
|
13
|
+
React.createElement("circle", { cx: "16", cy: "6", r: "2" }),
|
|
14
|
+
React.createElement("circle", { cx: "8", cy: "12", r: "2" }),
|
|
15
|
+
React.createElement("circle", { cx: "16", cy: "12", r: "2" }),
|
|
16
|
+
React.createElement("circle", { cx: "8", cy: "18", r: "2" }),
|
|
17
|
+
React.createElement("circle", { cx: "16", cy: "18", r: "2" })));
|
|
18
|
+
const DefaultEditIcon = () => (React.createElement("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "currentColor" },
|
|
19
|
+
React.createElement("path", { d: "M3 17.25V21h3.75L17.81 9.94l-3.75-3.75L3 17.25zM20.71 7.04c.39-.39.39-1.02 0-1.41l-2.34-2.34c-.39-.39-1.02-.39-1.41 0l-1.83 1.83 3.75 3.75 1.83-1.83z" })));
|
|
20
|
+
const DefaultStyleIcon = () => (React.createElement("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "currentColor" },
|
|
21
|
+
React.createElement("path", { d: "M12 3c-4.97 0-9 4.03-9 9s4.03 9 9 9c.83 0 1.5-.67 1.5-1.5 0-.39-.15-.74-.39-1.01-.23-.26-.38-.61-.38-.99 0-.83.67-1.5 1.5-1.5H16c2.76 0 5-2.24 5-5 0-4.42-4.03-8-9-8zm-5.5 9c-.83 0-1.5-.67-1.5-1.5S5.67 9 6.5 9 8 9.67 8 10.5 7.33 12 6.5 12zm3-4C8.67 8 8 7.33 8 6.5S8.67 5 9.5 5s1.5.67 1.5 1.5S10.33 8 9.5 8zm5 0c-.83 0-1.5-.67-1.5-1.5S13.67 5 14.5 5s1.5.67 1.5 1.5S15.33 8 14.5 8zm3 4c-.83 0-1.5-.67-1.5-1.5S16.67 9 17.5 9s1.5.67 1.5 1.5-.67 1.5-1.5 1.5z" })));
|
|
22
|
+
const DefaultDeleteIcon = () => (React.createElement("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "currentColor" },
|
|
23
|
+
React.createElement("path", { d: "M6 19c0 1.1.9 2 2 2h8c1.1 0 2-.9 2-2V7H6v12zM19 4h-3.5l-1-1h-5l-1 1H5v2h14V4z" })));
|
|
24
|
+
// Default color presets
|
|
25
|
+
const DEFAULT_BACKGROUND_PRESETS = ["transparent", "#ffffc8", "#ffcdd2", "#c8e6c9", "#bbdefb", "#e1bee7"];
|
|
26
|
+
const DEFAULT_TEXT_PRESETS = ["#333333", "#d32f2f", "#1976d2", "#388e3c", "#7b1fa2"];
|
|
27
|
+
export const FreetextHighlight = ({ highlight, onChange, onTextChange, onStyleChange, isScrolledTo, bounds, onContextMenu, onEditStart, onEditEnd, style, color = "#333333", backgroundColor = "#ffffc8", fontFamily = "inherit", fontSize = "14px", dragIcon, editIcon, styleIcon, backgroundColorPresets = DEFAULT_BACKGROUND_PRESETS, textColorPresets = DEFAULT_TEXT_PRESETS, onDelete, deleteIcon, }) => {
|
|
28
|
+
const [isEditing, setIsEditing] = useState(false);
|
|
29
|
+
const [isStylePanelOpen, setIsStylePanelOpen] = useState(false);
|
|
30
|
+
const [text, setText] = useState(highlight.content?.text || "");
|
|
31
|
+
const textareaRef = useRef(null);
|
|
32
|
+
const stylePanelRef = useRef(null);
|
|
33
|
+
// Sync text with highlight content when it changes externally
|
|
34
|
+
useEffect(() => {
|
|
35
|
+
setText(highlight.content?.text || "");
|
|
36
|
+
}, [highlight.content?.text]);
|
|
37
|
+
// Focus textarea when entering edit mode
|
|
38
|
+
useEffect(() => {
|
|
39
|
+
if (isEditing && textareaRef.current) {
|
|
40
|
+
textareaRef.current.focus();
|
|
41
|
+
textareaRef.current.select();
|
|
42
|
+
}
|
|
43
|
+
}, [isEditing]);
|
|
44
|
+
// Close style panel when clicking outside
|
|
45
|
+
useEffect(() => {
|
|
46
|
+
if (!isStylePanelOpen)
|
|
47
|
+
return;
|
|
48
|
+
const handleClickOutside = (e) => {
|
|
49
|
+
if (stylePanelRef.current && !stylePanelRef.current.contains(e.target)) {
|
|
50
|
+
setIsStylePanelOpen(false);
|
|
51
|
+
}
|
|
52
|
+
};
|
|
53
|
+
// Delay adding listener to avoid immediate close
|
|
54
|
+
const timeoutId = setTimeout(() => {
|
|
55
|
+
document.addEventListener("mousedown", handleClickOutside);
|
|
56
|
+
}, 0);
|
|
57
|
+
return () => {
|
|
58
|
+
clearTimeout(timeoutId);
|
|
59
|
+
document.removeEventListener("mousedown", handleClickOutside);
|
|
60
|
+
};
|
|
61
|
+
}, [isStylePanelOpen]);
|
|
62
|
+
const highlightClass = isScrolledTo ? "FreetextHighlight--scrolledTo" : "";
|
|
63
|
+
const editingClass = isEditing ? "FreetextHighlight--editing" : "";
|
|
64
|
+
// Generate key based on position for Rnd remount on position changes
|
|
65
|
+
const key = `${highlight.position.boundingRect.width}${highlight.position.boundingRect.height}${highlight.position.boundingRect.left}${highlight.position.boundingRect.top}`;
|
|
66
|
+
const handleTextClick = (e) => {
|
|
67
|
+
e.stopPropagation();
|
|
68
|
+
if (!isEditing) {
|
|
69
|
+
setIsEditing(true);
|
|
70
|
+
onEditStart?.();
|
|
71
|
+
}
|
|
72
|
+
};
|
|
73
|
+
const handleTextBlur = () => {
|
|
74
|
+
if (isEditing) {
|
|
75
|
+
setIsEditing(false);
|
|
76
|
+
onTextChange?.(text);
|
|
77
|
+
onEditEnd?.();
|
|
78
|
+
}
|
|
79
|
+
};
|
|
80
|
+
const handleKeyDown = (e) => {
|
|
81
|
+
if (e.key === "Escape") {
|
|
82
|
+
e.preventDefault();
|
|
83
|
+
setText(highlight.content?.text || "");
|
|
84
|
+
setIsEditing(false);
|
|
85
|
+
onEditEnd?.();
|
|
86
|
+
}
|
|
87
|
+
else if (e.key === "Enter" && !e.shiftKey) {
|
|
88
|
+
e.preventDefault();
|
|
89
|
+
setIsEditing(false);
|
|
90
|
+
onTextChange?.(text);
|
|
91
|
+
onEditEnd?.();
|
|
92
|
+
}
|
|
93
|
+
};
|
|
94
|
+
const containerStyle = {
|
|
95
|
+
backgroundColor,
|
|
96
|
+
color,
|
|
97
|
+
fontFamily,
|
|
98
|
+
fontSize,
|
|
99
|
+
...style,
|
|
100
|
+
};
|
|
101
|
+
return (React.createElement("div", { className: `FreetextHighlight ${highlightClass} ${editingClass}`, onContextMenu: onContextMenu },
|
|
102
|
+
React.createElement(Rnd, { className: "FreetextHighlight__rnd", onDragStop: (_, data) => {
|
|
103
|
+
const boundingRect = {
|
|
104
|
+
...highlight.position.boundingRect,
|
|
105
|
+
top: data.y,
|
|
106
|
+
left: data.x,
|
|
107
|
+
};
|
|
108
|
+
onChange?.(boundingRect);
|
|
109
|
+
}, onDragStart: () => {
|
|
110
|
+
if (!isEditing) {
|
|
111
|
+
onEditStart?.();
|
|
112
|
+
}
|
|
113
|
+
}, default: {
|
|
114
|
+
x: highlight.position.boundingRect.left,
|
|
115
|
+
y: highlight.position.boundingRect.top,
|
|
116
|
+
width: highlight.position.boundingRect.width || 150,
|
|
117
|
+
height: highlight.position.boundingRect.height || 80,
|
|
118
|
+
}, minWidth: 100, minHeight: 50, key: key, bounds: bounds, enableResizing: {
|
|
119
|
+
top: false,
|
|
120
|
+
right: true,
|
|
121
|
+
bottom: true,
|
|
122
|
+
left: false,
|
|
123
|
+
topRight: false,
|
|
124
|
+
bottomRight: true,
|
|
125
|
+
bottomLeft: false,
|
|
126
|
+
topLeft: false,
|
|
127
|
+
}, onResizeStop: (_e, _direction, ref, _delta, position) => {
|
|
128
|
+
const boundingRect = {
|
|
129
|
+
top: position.y,
|
|
130
|
+
left: position.x,
|
|
131
|
+
width: ref.offsetWidth,
|
|
132
|
+
height: ref.offsetHeight,
|
|
133
|
+
pageNumber: getPageFromElement(ref)?.number ||
|
|
134
|
+
highlight.position.boundingRect.pageNumber,
|
|
135
|
+
};
|
|
136
|
+
onChange?.(boundingRect);
|
|
137
|
+
}, onResizeStart: () => {
|
|
138
|
+
if (!isEditing) {
|
|
139
|
+
onEditStart?.();
|
|
140
|
+
}
|
|
141
|
+
}, cancel: ".FreetextHighlight__text, .FreetextHighlight__input, .FreetextHighlight__edit-button, .FreetextHighlight__style-button, .FreetextHighlight__style-panel, .FreetextHighlight__delete-button" },
|
|
142
|
+
React.createElement("div", { className: "FreetextHighlight__container", style: containerStyle },
|
|
143
|
+
React.createElement("div", { className: "FreetextHighlight__toolbar" },
|
|
144
|
+
React.createElement("div", { className: "FreetextHighlight__drag-handle", title: "Drag to move" }, dragIcon || React.createElement(DefaultDragIcon, null)),
|
|
145
|
+
React.createElement("button", { className: "FreetextHighlight__edit-button", onClick: handleTextClick, title: "Edit text", type: "button" }, editIcon || React.createElement(DefaultEditIcon, null)),
|
|
146
|
+
React.createElement("button", { className: "FreetextHighlight__style-button", onClick: (e) => {
|
|
147
|
+
e.stopPropagation();
|
|
148
|
+
setIsStylePanelOpen(!isStylePanelOpen);
|
|
149
|
+
}, title: "Change style", type: "button" }, styleIcon || React.createElement(DefaultStyleIcon, null)),
|
|
150
|
+
onDelete && (React.createElement("button", { className: "FreetextHighlight__delete-button", onClick: (e) => {
|
|
151
|
+
e.stopPropagation();
|
|
152
|
+
onDelete();
|
|
153
|
+
}, title: "Delete", type: "button" }, deleteIcon || React.createElement(DefaultDeleteIcon, null)))),
|
|
154
|
+
isStylePanelOpen && (React.createElement("div", { className: "FreetextHighlight__style-panel", ref: stylePanelRef, onClick: (e) => e.stopPropagation() },
|
|
155
|
+
React.createElement("div", { className: "FreetextHighlight__style-row" },
|
|
156
|
+
React.createElement("label", null, "Background"),
|
|
157
|
+
React.createElement("div", { className: "FreetextHighlight__color-options" },
|
|
158
|
+
React.createElement("div", { className: "FreetextHighlight__color-presets" }, backgroundColorPresets.map((c) => (React.createElement("button", { key: c, type: "button", className: `FreetextHighlight__color-preset ${c === "transparent" ? "FreetextHighlight__color-preset--transparent" : ""} ${backgroundColor === c ? "active" : ""}`, style: c !== "transparent" ? { backgroundColor: c } : undefined, onClick: () => onStyleChange?.({ backgroundColor: c }), title: c === "transparent" ? "No background" : c })))),
|
|
159
|
+
React.createElement("input", { type: "color", value: backgroundColor === "transparent" ? "#ffffff" : backgroundColor, onChange: (e) => {
|
|
160
|
+
onStyleChange?.({ backgroundColor: e.target.value });
|
|
161
|
+
} }))),
|
|
162
|
+
React.createElement("div", { className: "FreetextHighlight__style-row" },
|
|
163
|
+
React.createElement("label", null, "Text Color"),
|
|
164
|
+
React.createElement("div", { className: "FreetextHighlight__color-options" },
|
|
165
|
+
React.createElement("div", { className: "FreetextHighlight__color-presets" }, textColorPresets.map((c) => (React.createElement("button", { key: c, type: "button", className: `FreetextHighlight__color-preset ${color === c ? "active" : ""}`, style: { backgroundColor: c }, onClick: () => onStyleChange?.({ color: c }), title: c })))),
|
|
166
|
+
React.createElement("input", { type: "color", value: color, onChange: (e) => {
|
|
167
|
+
onStyleChange?.({ color: e.target.value });
|
|
168
|
+
} }))),
|
|
169
|
+
React.createElement("div", { className: "FreetextHighlight__style-row" },
|
|
170
|
+
React.createElement("label", null, "Font Size"),
|
|
171
|
+
React.createElement("select", { value: fontSize, onChange: (e) => {
|
|
172
|
+
onStyleChange?.({ fontSize: e.target.value });
|
|
173
|
+
} },
|
|
174
|
+
React.createElement("option", { value: "10px" }, "10px"),
|
|
175
|
+
React.createElement("option", { value: "12px" }, "12px"),
|
|
176
|
+
React.createElement("option", { value: "14px" }, "14px"),
|
|
177
|
+
React.createElement("option", { value: "16px" }, "16px"),
|
|
178
|
+
React.createElement("option", { value: "18px" }, "18px"),
|
|
179
|
+
React.createElement("option", { value: "20px" }, "20px"),
|
|
180
|
+
React.createElement("option", { value: "24px" }, "24px"))),
|
|
181
|
+
React.createElement("div", { className: "FreetextHighlight__style-row" },
|
|
182
|
+
React.createElement("label", null, "Font"),
|
|
183
|
+
React.createElement("select", { value: fontFamily, onChange: (e) => {
|
|
184
|
+
onStyleChange?.({ fontFamily: e.target.value });
|
|
185
|
+
} },
|
|
186
|
+
React.createElement("option", { value: "inherit" }, "Default"),
|
|
187
|
+
React.createElement("option", { value: "Arial, sans-serif" }, "Arial"),
|
|
188
|
+
React.createElement("option", { value: "Georgia, serif" }, "Georgia"),
|
|
189
|
+
React.createElement("option", { value: "'Courier New', monospace" }, "Courier"),
|
|
190
|
+
React.createElement("option", { value: "'Times New Roman', serif" }, "Times"))))),
|
|
191
|
+
React.createElement("div", { className: "FreetextHighlight__content" }, isEditing ? (React.createElement("textarea", { ref: textareaRef, className: "FreetextHighlight__input", value: text, onChange: (e) => setText(e.target.value), onBlur: handleTextBlur, onKeyDown: handleKeyDown, onClick: (e) => e.stopPropagation() })) : (React.createElement("div", { className: "FreetextHighlight__text" }, text || "New note")))))));
|
|
192
|
+
};
|
|
193
|
+
//# sourceMappingURL=FreetextHighlight.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FreetextHighlight.js","sourceRoot":"","sources":["../../../src/components/FreetextHighlight.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { PDFViewer } from "pdfjs-dist/types/web/pdf_viewer";
|
|
2
|
+
import React, { ReactNode } from "react";
|
|
3
|
+
import { GhostHighlight, Highlight, HighlightBindings } from "../types";
|
|
4
|
+
/**
|
|
5
|
+
* The props type for {@link HighlightLayer}.
|
|
6
|
+
*
|
|
7
|
+
* @category Component Properties
|
|
8
|
+
* @internal
|
|
9
|
+
*/
|
|
10
|
+
export interface HighlightLayerProps {
|
|
11
|
+
/**
|
|
12
|
+
* Highlights and GhostHighlights organised by page number.
|
|
13
|
+
*/
|
|
14
|
+
highlightsByPage: {
|
|
15
|
+
[pageNumber: number]: Array<Highlight | GhostHighlight>;
|
|
16
|
+
};
|
|
17
|
+
/**
|
|
18
|
+
* The page number of the PDF document to highlight (1 indexed).
|
|
19
|
+
*/
|
|
20
|
+
pageNumber: number;
|
|
21
|
+
/**
|
|
22
|
+
* ID of the highlight that the parent PDF Highlighter is trying to autoscroll to.
|
|
23
|
+
*/
|
|
24
|
+
scrolledToHighlightId?: string | null;
|
|
25
|
+
/**
|
|
26
|
+
* The PDFViewer instance containing the HighlightLayer
|
|
27
|
+
*/
|
|
28
|
+
viewer: PDFViewer;
|
|
29
|
+
/**
|
|
30
|
+
* Group of DOM refs for all the highlights on this layer.
|
|
31
|
+
*/
|
|
32
|
+
highlightBindings: HighlightBindings;
|
|
33
|
+
/**
|
|
34
|
+
* The Highlight container that should be used to render highlights for this layer.
|
|
35
|
+
* It will be given appropriate context for a single highlight, allowing it to render
|
|
36
|
+
* a single {@link TextHighlight}, {@link AreaHighlight}, etc., in the correct place.
|
|
37
|
+
*/
|
|
38
|
+
children: ReactNode;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* A component responsible for managing all the highlights and ghost highlights
|
|
42
|
+
* for a single page of a PDF document. It does not render each highlight
|
|
43
|
+
* but it provides context for a highlight container to do so.
|
|
44
|
+
* Its rendering should be controlled by a {@link PdfHighlighter}.
|
|
45
|
+
*
|
|
46
|
+
* @category Component
|
|
47
|
+
* @internal
|
|
48
|
+
*/
|
|
49
|
+
export declare const HighlightLayer: ({ highlightsByPage, pageNumber, scrolledToHighlightId, viewer, highlightBindings, children, }: HighlightLayerProps) => React.JSX.Element;
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { HighlightContext, } from "../contexts/HighlightContext";
|
|
3
|
+
import { scaledPositionToViewport, viewportToScaled } from "../lib/coordinates";
|
|
4
|
+
import screenshot from "../lib/screenshot";
|
|
5
|
+
const EMPTY_ID = "empty-id";
|
|
6
|
+
/**
|
|
7
|
+
* A component responsible for managing all the highlights and ghost highlights
|
|
8
|
+
* for a single page of a PDF document. It does not render each highlight
|
|
9
|
+
* but it provides context for a highlight container to do so.
|
|
10
|
+
* Its rendering should be controlled by a {@link PdfHighlighter}.
|
|
11
|
+
*
|
|
12
|
+
* @category Component
|
|
13
|
+
* @internal
|
|
14
|
+
*/
|
|
15
|
+
export const HighlightLayer = ({ highlightsByPage, pageNumber, scrolledToHighlightId, viewer, highlightBindings, children, }) => {
|
|
16
|
+
const currentHighlights = highlightsByPage[pageNumber] || [];
|
|
17
|
+
return (React.createElement("div", null, currentHighlights.map((highlight, index) => {
|
|
18
|
+
const viewportHighlight = {
|
|
19
|
+
...highlight,
|
|
20
|
+
id: "id" in highlight ? highlight.id : EMPTY_ID, // Give Empty ID to GhostHighlight
|
|
21
|
+
position: scaledPositionToViewport(highlight.position, viewer),
|
|
22
|
+
};
|
|
23
|
+
const isScrolledTo = Boolean(scrolledToHighlightId === viewportHighlight.id);
|
|
24
|
+
const highlightUtils = {
|
|
25
|
+
highlight: viewportHighlight,
|
|
26
|
+
viewportToScaled: (rect) => {
|
|
27
|
+
const viewport = viewer.getPageView((rect.pageNumber || pageNumber) - 1).viewport;
|
|
28
|
+
return viewportToScaled(rect, viewport);
|
|
29
|
+
},
|
|
30
|
+
screenshot: (boundingRect) => screenshot(boundingRect, pageNumber, viewer),
|
|
31
|
+
isScrolledTo: isScrolledTo,
|
|
32
|
+
highlightBindings,
|
|
33
|
+
};
|
|
34
|
+
return (React.createElement(HighlightContext.Provider, { value: highlightUtils, key: index }, children));
|
|
35
|
+
})));
|
|
36
|
+
};
|
|
37
|
+
//# sourceMappingURL=HighlightLayer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"HighlightLayer.js","sourceRoot":"","sources":["../../../src/components/HighlightLayer.tsx"],"names":[],"mappings":"AACA,OAAO,KAAoB,MAAM,OAAO,CAAC;AACzC,OAAO,EAEL,gBAAgB,GACjB,MAAM,8BAA8B,CAAC;AACtC,OAAO,EAAE,wBAAwB,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAChF,OAAO,UAAU,MAAM,mBAAmB,CAAC;AAU3C,MAAM,QAAQ,GAAG,UAAU,CAAC;AA0C5B;;;;;;;;GAQG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,EAC7B,gBAAgB,EAChB,UAAU,EACV,qBAAqB,EACrB,MAAM,EACN,iBAAiB,EACjB,QAAQ,GACY,EAAE,EAAE;IACxB,MAAM,iBAAiB,GAAG,gBAAgB,CAAC,UAAU,CAAC,IAAI,EAAE,CAAC;IAE7D,OAAO,CACL,iCACG,iBAAiB,CAAC,GAAG,CAAC,CAAC,SAAS,EAAE,KAAK,EAAE,EAAE;QAC1C,MAAM,iBAAiB,GAAsB;YAC3C,GAAG,SAAS;YACZ,EAAE,EAAE,IAAI,IAAI,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,EAAE,kCAAkC;YACnF,QAAQ,EAAE,wBAAwB,CAAC,SAAS,CAAC,QAAQ,EAAE,MAAM,CAAC;SAC/D,CAAC;QAEF,MAAM,YAAY,GAAG,OAAO,CAC1B,qBAAqB,KAAK,iBAAiB,CAAC,EAAE,CAC/C,CAAC;QAEF,MAAM,cAAc,GAA4B;YAC9C,SAAS,EAAE,iBAAiB;YAC5B,gBAAgB,EAAE,CAAC,IAAW,EAAE,EAAE;gBAChC,MAAM,QAAQ,GAAG,MAAM,CAAC,WAAW,CACjC,CAAC,IAAI,CAAC,UAAU,IAAI,UAAU,CAAC,GAAG,CAAC,CACpC,CAAC,QAAQ,CAAC;gBAEX,OAAO,gBAAgB,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;YAC1C,CAAC;YACD,UAAU,EAAE,CAAC,YAAkB,EAAE,EAAE,CACjC,UAAU,CAAC,YAAY,EAAE,UAAU,EAAE,MAAM,CAAC;YAC9C,YAAY,EAAE,YAAY;YAC1B,iBAAiB;SAClB,CAAC;QAEF,OAAO,CACL,oBAAC,gBAAgB,CAAC,QAAQ,IAAC,KAAK,EAAE,cAAc,EAAE,GAAG,EAAE,KAAK,IACzD,QAAQ,CACiB,CAC7B,CAAC;IACJ,CAAC,CAAC,CACE,CACP,CAAC;AACJ,CAAC,CAAC"}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import React, { CSSProperties, MouseEvent, ReactNode } from "react";
|
|
2
|
+
import "../style/ImageHighlight.css";
|
|
3
|
+
import type { LTWHP, ViewportHighlight } from "../types";
|
|
4
|
+
/**
|
|
5
|
+
* The props type for {@link ImageHighlight}.
|
|
6
|
+
*
|
|
7
|
+
* @category Component Properties
|
|
8
|
+
*/
|
|
9
|
+
export interface ImageHighlightProps {
|
|
10
|
+
/**
|
|
11
|
+
* The highlight to be rendered as an {@link ImageHighlight}.
|
|
12
|
+
* The highlight.content.image should contain the image data URL.
|
|
13
|
+
*/
|
|
14
|
+
highlight: ViewportHighlight;
|
|
15
|
+
/**
|
|
16
|
+
* A callback triggered whenever the highlight position or size changes.
|
|
17
|
+
*
|
|
18
|
+
* @param rect - The updated highlight area.
|
|
19
|
+
*/
|
|
20
|
+
onChange?(rect: LTWHP): void;
|
|
21
|
+
/**
|
|
22
|
+
* Has the highlight been auto-scrolled into view?
|
|
23
|
+
*/
|
|
24
|
+
isScrolledTo?: boolean;
|
|
25
|
+
/**
|
|
26
|
+
* react-rnd bounds on the highlight area.
|
|
27
|
+
*/
|
|
28
|
+
bounds?: string | Element;
|
|
29
|
+
/**
|
|
30
|
+
* A callback triggered on context menu.
|
|
31
|
+
*/
|
|
32
|
+
onContextMenu?(event: MouseEvent<HTMLDivElement>): void;
|
|
33
|
+
/**
|
|
34
|
+
* Event called when editing begins (drag or resize).
|
|
35
|
+
*/
|
|
36
|
+
onEditStart?(): void;
|
|
37
|
+
/**
|
|
38
|
+
* Event called when editing ends.
|
|
39
|
+
*/
|
|
40
|
+
onEditEnd?(): void;
|
|
41
|
+
/**
|
|
42
|
+
* Custom styling for the container.
|
|
43
|
+
*/
|
|
44
|
+
style?: CSSProperties;
|
|
45
|
+
/**
|
|
46
|
+
* Custom drag icon. Replaces the default 6-dot grid icon.
|
|
47
|
+
*/
|
|
48
|
+
dragIcon?: ReactNode;
|
|
49
|
+
/**
|
|
50
|
+
* Callback triggered when the delete button is clicked.
|
|
51
|
+
*/
|
|
52
|
+
onDelete?(): void;
|
|
53
|
+
/**
|
|
54
|
+
* Custom delete icon. Replaces the default trash icon.
|
|
55
|
+
*/
|
|
56
|
+
deleteIcon?: ReactNode;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Renders a draggable, resizable image/signature annotation.
|
|
60
|
+
*
|
|
61
|
+
* @category Component
|
|
62
|
+
*/
|
|
63
|
+
export declare const ImageHighlight: ({ highlight, onChange, isScrolledTo, bounds, onContextMenu, onEditStart, onEditEnd, style, dragIcon, onDelete, deleteIcon, }: ImageHighlightProps) => React.JSX.Element;
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { Rnd } from "react-rnd";
|
|
3
|
+
import { getPageFromElement } from "../lib/pdfjs-dom";
|
|
4
|
+
import "../style/ImageHighlight.css";
|
|
5
|
+
/**
|
|
6
|
+
* Default drag icon - 6 dot grid pattern.
|
|
7
|
+
*/
|
|
8
|
+
const DefaultDragIcon = () => (React.createElement("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "currentColor" },
|
|
9
|
+
React.createElement("circle", { cx: "8", cy: "6", r: "2" }),
|
|
10
|
+
React.createElement("circle", { cx: "16", cy: "6", r: "2" }),
|
|
11
|
+
React.createElement("circle", { cx: "8", cy: "12", r: "2" }),
|
|
12
|
+
React.createElement("circle", { cx: "16", cy: "12", r: "2" }),
|
|
13
|
+
React.createElement("circle", { cx: "8", cy: "18", r: "2" }),
|
|
14
|
+
React.createElement("circle", { cx: "16", cy: "18", r: "2" })));
|
|
15
|
+
const DefaultDeleteIcon = () => (React.createElement("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "currentColor" },
|
|
16
|
+
React.createElement("path", { d: "M6 19c0 1.1.9 2 2 2h8c1.1 0 2-.9 2-2V7H6v12zM19 4h-3.5l-1-1h-5l-1 1H5v2h14V4z" })));
|
|
17
|
+
/**
|
|
18
|
+
* Renders a draggable, resizable image/signature annotation.
|
|
19
|
+
*
|
|
20
|
+
* @category Component
|
|
21
|
+
*/
|
|
22
|
+
export const ImageHighlight = ({ highlight, onChange, isScrolledTo, bounds, onContextMenu, onEditStart, onEditEnd, style, dragIcon, onDelete, deleteIcon, }) => {
|
|
23
|
+
const highlightClass = isScrolledTo ? "ImageHighlight--scrolledTo" : "";
|
|
24
|
+
// Generate key based on position for Rnd remount on position changes
|
|
25
|
+
const key = `${highlight.position.boundingRect.width}${highlight.position.boundingRect.height}${highlight.position.boundingRect.left}${highlight.position.boundingRect.top}`;
|
|
26
|
+
const imageUrl = highlight.content?.image;
|
|
27
|
+
return (React.createElement("div", { className: `ImageHighlight ${highlightClass}`, onContextMenu: onContextMenu },
|
|
28
|
+
React.createElement(Rnd, { className: "ImageHighlight__rnd", onDragStop: (_, data) => {
|
|
29
|
+
const boundingRect = {
|
|
30
|
+
...highlight.position.boundingRect,
|
|
31
|
+
top: data.y,
|
|
32
|
+
left: data.x,
|
|
33
|
+
};
|
|
34
|
+
onChange?.(boundingRect);
|
|
35
|
+
onEditEnd?.();
|
|
36
|
+
}, onDragStart: onEditStart, onResizeStop: (_e, _direction, ref, _delta, position) => {
|
|
37
|
+
const boundingRect = {
|
|
38
|
+
top: position.y,
|
|
39
|
+
left: position.x,
|
|
40
|
+
width: ref.offsetWidth,
|
|
41
|
+
height: ref.offsetHeight,
|
|
42
|
+
pageNumber: getPageFromElement(ref)?.number ||
|
|
43
|
+
highlight.position.boundingRect.pageNumber,
|
|
44
|
+
};
|
|
45
|
+
onChange?.(boundingRect);
|
|
46
|
+
onEditEnd?.();
|
|
47
|
+
}, onResizeStart: onEditStart, default: {
|
|
48
|
+
x: highlight.position.boundingRect.left,
|
|
49
|
+
y: highlight.position.boundingRect.top,
|
|
50
|
+
width: highlight.position.boundingRect.width || 150,
|
|
51
|
+
height: highlight.position.boundingRect.height || 100,
|
|
52
|
+
}, minWidth: 50, minHeight: 50, key: key, bounds: bounds, lockAspectRatio: true, dragHandleClassName: "ImageHighlight__drag-handle", onClick: (event) => {
|
|
53
|
+
event.stopPropagation();
|
|
54
|
+
event.preventDefault();
|
|
55
|
+
}, style: style },
|
|
56
|
+
React.createElement("div", { className: "ImageHighlight__container" },
|
|
57
|
+
React.createElement("div", { className: "ImageHighlight__toolbar" },
|
|
58
|
+
React.createElement("div", { className: "ImageHighlight__drag-handle", title: "Drag to move" }, dragIcon || React.createElement(DefaultDragIcon, null)),
|
|
59
|
+
onDelete && (React.createElement("button", { className: "ImageHighlight__delete-button", onClick: (e) => {
|
|
60
|
+
e.stopPropagation();
|
|
61
|
+
onDelete();
|
|
62
|
+
}, title: "Delete", type: "button" }, deleteIcon || React.createElement(DefaultDeleteIcon, null)))),
|
|
63
|
+
React.createElement("div", { className: "ImageHighlight__content" }, imageUrl ? (React.createElement("img", { src: imageUrl, alt: "Highlight", className: "ImageHighlight__image", draggable: false })) : (React.createElement("div", { className: "ImageHighlight__placeholder" }, "No image")))))));
|
|
64
|
+
};
|
|
65
|
+
//# sourceMappingURL=ImageHighlight.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ImageHighlight.js","sourceRoot":"","sources":["../../../src/components/ImageHighlight.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import React, { ReactNode } from "react";
|
|
2
|
+
import { Tip } from "../types";
|
|
3
|
+
/**
|
|
4
|
+
* The props type for {@link MonitoredHighlightContainer}.
|
|
5
|
+
*
|
|
6
|
+
* @category Component Properties
|
|
7
|
+
*/
|
|
8
|
+
export interface MonitoredHighlightContainerProps {
|
|
9
|
+
/**
|
|
10
|
+
* A callback triggered whenever the mouse hovers over a highlight.
|
|
11
|
+
*/
|
|
12
|
+
onMouseEnter?(): void;
|
|
13
|
+
/**
|
|
14
|
+
* What tip to automatically display whenever a mouse hovers over a highlight.
|
|
15
|
+
* The tip will persist even as the user puts their mouse over it and not the
|
|
16
|
+
* highlight, but will disappear once it no longer hovers both.
|
|
17
|
+
*/
|
|
18
|
+
highlightTip?: Tip;
|
|
19
|
+
/**
|
|
20
|
+
* A callback triggered whenever the mouse completely moves out from both the
|
|
21
|
+
* highlight (children) and any highlightTip.
|
|
22
|
+
*/
|
|
23
|
+
onMouseLeave?(): void;
|
|
24
|
+
/**
|
|
25
|
+
* Component to monitor mouse activity over. This should be a highlight within the {@link PdfHighlighter}.
|
|
26
|
+
*/
|
|
27
|
+
children: ReactNode;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* A container for a highlight component that monitors whether a mouse is over a
|
|
31
|
+
* highlight and over some secondary highlight tip. It will display the tip
|
|
32
|
+
* whenever the mouse is over the highlight and it will hide the tip only when
|
|
33
|
+
* the mouse has left the highlight AND the tip.
|
|
34
|
+
*
|
|
35
|
+
* @category Component
|
|
36
|
+
*/
|
|
37
|
+
export declare const MonitoredHighlightContainer: ({ onMouseEnter, highlightTip, onMouseLeave, children, }: MonitoredHighlightContainerProps) => React.JSX.Element;
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import React, { useRef } from "react";
|
|
2
|
+
import { usePdfHighlighterContext } from "../contexts/PdfHighlighterContext";
|
|
3
|
+
import { MouseMonitor } from "./MouseMonitor";
|
|
4
|
+
/**
|
|
5
|
+
* A container for a highlight component that monitors whether a mouse is over a
|
|
6
|
+
* highlight and over some secondary highlight tip. It will display the tip
|
|
7
|
+
* whenever the mouse is over the highlight and it will hide the tip only when
|
|
8
|
+
* the mouse has left the highlight AND the tip.
|
|
9
|
+
*
|
|
10
|
+
* @category Component
|
|
11
|
+
*/
|
|
12
|
+
export const MonitoredHighlightContainer = ({ onMouseEnter, highlightTip, onMouseLeave, children, }) => {
|
|
13
|
+
const mouseInRef = useRef(false); // Whether the mouse is over the child (highlight)
|
|
14
|
+
const { setTip, isEditingOrHighlighting } = usePdfHighlighterContext();
|
|
15
|
+
return (React.createElement("div", { onMouseEnter: () => {
|
|
16
|
+
mouseInRef.current = true;
|
|
17
|
+
onMouseEnter && onMouseEnter();
|
|
18
|
+
if (isEditingOrHighlighting())
|
|
19
|
+
return;
|
|
20
|
+
if (highlightTip) {
|
|
21
|
+
// MouseMonitor the highlightTip to prevent it from disappearing if the mouse is over it and not the highlight.
|
|
22
|
+
const monitoredHighlightTip = (React.createElement(MouseMonitor, { onMoveAway: () => {
|
|
23
|
+
// The event will keep triggering if the mouse is not on the highlightTip,
|
|
24
|
+
// but don't do anything if the mouse is over the highlight.
|
|
25
|
+
if (mouseInRef.current) {
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
setTip(null);
|
|
29
|
+
onMouseLeave && onMouseLeave();
|
|
30
|
+
}, paddingX: 60, paddingY: 30 }, highlightTip.content));
|
|
31
|
+
setTip({
|
|
32
|
+
position: highlightTip.position,
|
|
33
|
+
content: monitoredHighlightTip,
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
}, onMouseLeave: () => {
|
|
37
|
+
mouseInRef.current = false;
|
|
38
|
+
// Trigger onMouseLeave if no highlightTip exists
|
|
39
|
+
!highlightTip && onMouseLeave && onMouseLeave();
|
|
40
|
+
} }, children));
|
|
41
|
+
};
|
|
42
|
+
//# sourceMappingURL=MonitoredHighlightContainer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MonitoredHighlightContainer.js","sourceRoot":"","sources":["../../../src/components/MonitoredHighlightContainer.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAa,MAAM,EAAE,MAAM,OAAO,CAAC;AACjD,OAAO,EAAE,wBAAwB,EAAE,MAAM,mCAAmC,CAAC;AAE7E,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAgC9C;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,2BAA2B,GAAG,CAAC,EAC1C,YAAY,EACZ,YAAY,EACZ,YAAY,EACZ,QAAQ,GACyB,EAAE,EAAE;IACrC,MAAM,UAAU,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,kDAAkD;IAEpF,MAAM,EAAE,MAAM,EAAE,uBAAuB,EAAE,GAAG,wBAAwB,EAAE,CAAC;IAEvE,OAAO,CACL,6BACE,YAAY,EAAE,GAAG,EAAE;YACjB,UAAU,CAAC,OAAO,GAAG,IAAI,CAAC;YAC1B,YAAY,IAAI,YAAY,EAAE,CAAC;YAE/B,IAAI,uBAAuB,EAAE;gBAAE,OAAO;YAEtC,IAAI,YAAY,EAAE,CAAC;gBACjB,+GAA+G;gBAC/G,MAAM,qBAAqB,GAAG,CAC5B,oBAAC,YAAY,IACX,UAAU,EAAE,GAAG,EAAE;wBACf,0EAA0E;wBAC1E,4DAA4D;wBAC5D,IAAI,UAAU,CAAC,OAAO,EAAE,CAAC;4BACvB,OAAO;wBACT,CAAC;wBAED,MAAM,CAAC,IAAI,CAAC,CAAC;wBACb,YAAY,IAAI,YAAY,EAAE,CAAC;oBACjC,CAAC,EACD,QAAQ,EAAE,EAAE,EACZ,QAAQ,EAAE,EAAE,IAEX,YAAY,CAAC,OAAO,CACR,CAChB,CAAC;gBAEF,MAAM,CAAC;oBACL,QAAQ,EAAE,YAAY,CAAC,QAAQ;oBAC/B,OAAO,EAAE,qBAAqB;iBAC/B,CAAC,CAAC;YACL,CAAC;QACH,CAAC,EACD,YAAY,EAAE,GAAG,EAAE;YACjB,UAAU,CAAC,OAAO,GAAG,KAAK,CAAC;YAE3B,iDAAiD;YACjD,CAAC,YAAY,IAAI,YAAY,IAAI,YAAY,EAAE,CAAC;QAClD,CAAC,IAEA,QAAQ,CACL,CACP,CAAC;AACJ,CAAC,CAAC"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import React, { ReactNode } from "react";
|
|
2
|
+
/**
|
|
3
|
+
* The props type for {@link MouseMonitor}.
|
|
4
|
+
*
|
|
5
|
+
* @category Component Properties
|
|
6
|
+
* @internal
|
|
7
|
+
*/
|
|
8
|
+
export interface MouseMonitorProps {
|
|
9
|
+
/**
|
|
10
|
+
* Callback triggered whenever the mouse moves not within the bounds of the
|
|
11
|
+
* child component. This will keep triggering as long as the component is
|
|
12
|
+
* rendered.
|
|
13
|
+
*/
|
|
14
|
+
onMoveAway(): void;
|
|
15
|
+
/**
|
|
16
|
+
* X padding in pixels for the container to monitor mouse activity in.
|
|
17
|
+
*/
|
|
18
|
+
paddingX: number;
|
|
19
|
+
/**
|
|
20
|
+
* Y padding in pixels for the container to monitor mouse activity in.
|
|
21
|
+
*/
|
|
22
|
+
paddingY: number;
|
|
23
|
+
/**
|
|
24
|
+
* Component over which mouse activity is monitored.
|
|
25
|
+
*/
|
|
26
|
+
children: ReactNode;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* A component that monitors mouse movements over a child and invisible padded area.
|
|
30
|
+
*
|
|
31
|
+
* @category Component
|
|
32
|
+
* @internal
|
|
33
|
+
*/
|
|
34
|
+
export declare const MouseMonitor: ({ onMoveAway, paddingX, paddingY, children, }: MouseMonitorProps) => React.JSX.Element;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import React, { useEffect, useRef } from "react";
|
|
2
|
+
/**
|
|
3
|
+
* A component that monitors mouse movements over a child and invisible padded area.
|
|
4
|
+
*
|
|
5
|
+
* @category Component
|
|
6
|
+
* @internal
|
|
7
|
+
*/
|
|
8
|
+
export const MouseMonitor = ({ onMoveAway, paddingX, paddingY, children, }) => {
|
|
9
|
+
const containerRef = useRef(null);
|
|
10
|
+
const onMouseMove = (event) => {
|
|
11
|
+
if (!containerRef.current)
|
|
12
|
+
return;
|
|
13
|
+
const { clientX, clientY } = event;
|
|
14
|
+
const { left, top, width, height } = containerRef.current.getBoundingClientRect();
|
|
15
|
+
const inBoundsX = clientX > left - paddingX && clientX < left + width + paddingX;
|
|
16
|
+
const inBoundsY = clientY > top - paddingY && clientY < top + height + paddingY;
|
|
17
|
+
if (!(inBoundsX && inBoundsY)) {
|
|
18
|
+
onMoveAway();
|
|
19
|
+
}
|
|
20
|
+
};
|
|
21
|
+
useEffect(() => {
|
|
22
|
+
// TODO: Maybe optimise or throttle?
|
|
23
|
+
document.addEventListener("mousemove", onMouseMove);
|
|
24
|
+
return () => {
|
|
25
|
+
document.removeEventListener("mousemove", onMouseMove);
|
|
26
|
+
};
|
|
27
|
+
}, []);
|
|
28
|
+
return React.createElement("div", { ref: containerRef }, children);
|
|
29
|
+
};
|
|
30
|
+
//# sourceMappingURL=MouseMonitor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MouseMonitor.js","sourceRoot":"","sources":["../../../src/components/MouseMonitor.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAa,SAAS,EAAE,MAAM,EAAE,MAAM,OAAO,CAAC;AAgC5D;;;;;GAKG;AACH,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,EAC3B,UAAU,EACV,QAAQ,EACR,QAAQ,EACR,QAAQ,GACU,EAAE,EAAE;IACtB,MAAM,YAAY,GAAG,MAAM,CAAwB,IAAI,CAAC,CAAC;IAEzD,MAAM,WAAW,GAAG,CAAC,KAAiB,EAAE,EAAE;QACxC,IAAI,CAAC,YAAY,CAAC,OAAO;YAAE,OAAO;QAElC,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,GAAG,KAAK,CAAC;QACnC,MAAM,EAAE,IAAI,EAAE,GAAG,EAAE,KAAK,EAAE,MAAM,EAAE,GAChC,YAAY,CAAC,OAAO,CAAC,qBAAqB,EAAE,CAAC;QAE/C,MAAM,SAAS,GACb,OAAO,GAAG,IAAI,GAAG,QAAQ,IAAI,OAAO,GAAG,IAAI,GAAG,KAAK,GAAG,QAAQ,CAAC;QACjE,MAAM,SAAS,GACb,OAAO,GAAG,GAAG,GAAG,QAAQ,IAAI,OAAO,GAAG,GAAG,GAAG,MAAM,GAAG,QAAQ,CAAC;QAEhE,IAAI,CAAC,CAAC,SAAS,IAAI,SAAS,CAAC,EAAE,CAAC;YAC9B,UAAU,EAAE,CAAC;QACf,CAAC;IACH,CAAC,CAAC;IAEF,SAAS,CAAC,GAAG,EAAE;QACb,oCAAoC;QACpC,QAAQ,CAAC,gBAAgB,CAAC,WAAW,EAAE,WAAW,CAAC,CAAC;QAEpD,OAAO,GAAG,EAAE;YACV,QAAQ,CAAC,mBAAmB,CAAC,WAAW,EAAE,WAAW,CAAC,CAAC;QACzD,CAAC,CAAC;IACJ,CAAC,EAAE,EAAE,CAAC,CAAC;IAEP,OAAO,6BAAK,GAAG,EAAE,YAAY,IAAG,QAAQ,CAAO,CAAC;AAClD,CAAC,CAAC"}
|