I am creating an epub viewer and using react-reader as my npm package to render the file. I am trying to highlight the text when selected. The documentation does provide a way to do it. But the approach I am trying is to open a context menu and only when the "Hightlight" button is selected then it should highlight the text.

This is the code for the reader page:
"use client";
import React, { useState, useEffect } from "react";
import { ReactReader } from "react-reader";
import Notes from "../_components/Notes";
import Discussions from "../_components/Discussions";
import { Rendition, Contents } from "epubjs";
import { get } from "http";
import ContextMenu from "../_lib/ContextMenu";
type ITextSelection = {
text: string;
cfiRange: string;
};
const initialContextMenu = {
show: false,
x: 0,
y: 0,
};
function Reader() {
const [location, setLocation] = useState<string | number>(0);
const [discussions, setDiscussions] = useState("showDiscussions");
const [searchText, setSearchText] = useState("");
const [selections, setSelections] = useState<ITextSelection[]>([]);
const [rendition, setRendition] = useState<Rendition | undefined>(undefined);
const handleSearch = () => {
// Perform search logic here
};
function setRenderSelection(cfiRange: string, contents: Contents) {
if (rendition) {
setSelections((list) =>
list.concat({
text: rendition.getRange(cfiRange).toString(),
cfiRange,
})
);
rendition.annotations.add("highlight", cfiRange, {}, undefined, "hl", {
fill: "yellow",
"fill-opacity": "0.3",
"mix-blend-mode": "multiply",
});
const selection = contents.window.getSelection();
selection?.removeAllRanges();
console.log(selection);
}
}
useEffect(() => {
if (rendition) {
// rendition.on("selected", setRenderSelection);
rendition.on("selected", (rendition: Rendition, iframe: Window) => {
console.log("Rendition rendered");
iframe.document.documentElement.addEventListener(
"contextmenu",
(event: MouseEvent) => {
console.log("Stopping contextual menu coming from epubjs iframe");
event.preventDefault();
setcontextMenu((prev) => ({
show: true,
x: event.pageX,
y: event.pageY,
}));
}
);
});
console.log(selections);
return () => {
rendition?.off("selected", setRenderSelection);
};
}
}, [setSelections, rendition]);
const [contextMenu, setcontextMenu] = useState(initialContextMenu);
function handleContextMenu(e: React.MouseEvent) {
e.preventDefault();
console.log("right click");
const { pageX, pageY } = e;
setcontextMenu((prev) => ({
show: true,
x: pageX,
y: pageY,
}));
}
return (
<div className="h-screen">
<div className="grid grid-cols-2 grid-rows-3 gap-3 h-screen">
<div className="row-span-3 h-screen py-2 rounded-lg">
{/* Reader Section */}
<div className="h-full rounded-lg" onContextMenu={handleContextMenu}>
<ReactReader
url="https://react-reader.metabits.no/files/alice.epub"
location={location}
locationChanged={(epubcfi: string) => setLocation(epubcfi)}
getRendition={(_rendition: Rendition) => {
_rendition.themes.default({
"::selection": {
background: "rgba(255,255,0, 0.3)",
},
body: {
color: "black",
fontSize: "1.2em",
textIndent: "2em",
lineHeight: "1.6",
padding: "0",
margin: "0",
},
});
setRendition(_rendition);
}}
/>
</div>
</div>
<div className="row-span-2 bg-white mt-2 mr-2 rounded-lg overflow-hidden ">
{contextMenu.show && (
<ContextMenu x={contextMenu.x} y={contextMenu.y} />
)}
{/* Discussions/ Notes Section */}
<div className="w-full h-16 rounded-s-lg">
<div className="h-full bg-white rounded-lg">
<div className="h-full rounded-lg">
<div className="flex justify-evenly items-center pt-4 h-full w-full">
<button
className={`h-full w-full m-2 rounded-lg ${
discussions === "showDiscussions"
? "bg-textColor text-white"
: "bg-white"
} `}
onClick={() => setDiscussions("showDiscussions")}
>
Discussions
</button>
<button
className={`h-full w-full m-2 rounded-lg ${
discussions === "showNotes"
? "bg-textColor text-white"
: "bg-white"
}`}
onClick={() => setDiscussions("showNotes")}
>
Notes
</button>
</div>
</div>
</div>
</div>
<div className="h-full mb-4 overflow-scroll scroll-m-0">
{discussions === "showDiscussions" ? <Discussions /> : <Notes />}
</div>
</div>
<div className="col-start-2 row-start-3 mb-2 mr-2 bg-white rounded-lg">
{/*
Profile Section
*/}
</div>
</div>
</div>
);
}
export default Reader;
And here is the code for the context Menu:
import { FC } from "react";
interface IContextMenu {
x: number;
y: number;
}
const ContextMenu: FC<IContextMenu> = ({ x, y }) => {
return (
<div
className="context-menu"
style={{
position: "absolute",
top: y + 50,
left: x + 250,
zIndex: 10000,
backgroundColor: "white",
border: "1px solid #ccc",
borderRadius: "5px",
padding: "0",
margin: "0",
}}
>
<ul className="list-none">
<li
className="hover:bg-gray-200 p-2 cursor-pointer"
onClick={() => {
console.log("Copy");
}}
>
Copy
</li>
<li
className="hover:bg-gray-200 p-2 cursor-pointer"
onClick={() => {
console.log("Highlight");
}}
>
Highlight
</li>
<li
className="hover:bg-gray-200 p-2 cursor-pointer"
onClick={() => {
console.log("Bookmark");
}}
>
Bookmark
</li>
<li
className="hover:bg-gray-200 p-2 cursor-pointer"
onClick={() => {
console.log("Note");
}}
>
Note
</li>
</ul>
</div>
);
};
export default ContextMenu;
Does anyone have any intuition as to how should i go about it?