@huridocs/react-text-selection-handler
Version:
React pdf handler allows to render a PDF and handle text selection and highlights.
76 lines • 3.02 kB
JavaScript
import React, { useRef, useEffect } from 'react';
import { elementContainsDomRect } from './elementContainsDomRect';
import { rangeToTextRects } from './rangeToTextRects';
import { domRectToSelectionRectangle } from './TextSelection';
import { getSelectedText } from './getSelectedText';
const notNull = (value) => value !== null;
const normalizedFirefoxRange = (selection) => {
const finalRange = selection.getRangeAt(selection.rangeCount - 1);
const firstRange = selection.getRangeAt(0);
const range = document.createRange();
range.setStart(firstRange.startContainer, firstRange.startOffset);
range.setEnd(finalRange.endContainer, finalRange.endOffset);
return range;
};
const HandleTextSelection = ({ onSelect, onDeselect = () => { }, children, }) => {
const ref = useRef(null);
const getSelection = () => {
const selection = window.getSelection();
if (!ref.current) {
return;
}
if (!(selection === null || selection === void 0 ? void 0 : selection.toString().trim())) {
onDeselect();
return;
}
const regionElements = Array.from(ref.current.querySelectorAll('div[data-region-selector-id]'));
const range = normalizedFirefoxRange(selection);
const selectionRectangles = rangeToTextRects(range)
.map(rectangle => {
const region = regionElements.find(elementContainsDomRect(rectangle));
if (!region) {
return null;
}
return domRectToSelectionRectangle(rectangle, region);
})
.filter(notNull);
const text = getSelectedText();
onSelect({ text, selectionRectangles });
};
useEffect(() => {
const refElement = ref.current;
if (!refElement) {
return () => { };
}
const handleKeyDown = (event) => {
if ((event.ctrlKey || event.metaKey) && event.key === 'c') {
event.preventDefault();
const selection = window.getSelection();
if (selection && selection.toString().trim()) {
const text = getSelectedText();
navigator.clipboard.writeText(text);
}
}
};
refElement.addEventListener('keydown', handleKeyDown);
return () => {
refElement.removeEventListener('keydown', handleKeyDown);
};
}, [ref]);
return (React.createElement("div", { role: "none", ref: ref, onMouseDown: e => {
var _a;
if (e.button !== 0) {
return;
}
if (!e.shiftKey) {
(_a = window.getSelection()) === null || _a === void 0 ? void 0 : _a.removeAllRanges();
}
}, onMouseUp: e => {
if (e.button !== 0) {
return;
}
getSelection();
} }, children));
};
export { HandleTextSelection };
//# sourceMappingURL=HandleTextSelection.js.map