ReactJS Selectable Highlight
Checkout the repository by clicking on the image or here!
What is a Selectable Highlight?
A Selectable Highlight is a React component which I created to better allow the selection and highlighting of text for annotations. Selectable Highlight is a mini-project that I did for a larger project of mine which utilizes Selectable Highlight's functionality. Check it out below (try selecting some text to add a highlight)!
The UI of Selectable Highlight allows the user to make a selection in the text they see. Then, a side box will pop up either below or to the side. The user may chose the color of the highlight from a drop down and then click "Add Highlight" to add in the highlight. Some notable features are that Selectable Highlight allows the user to make highlights which overlap, and in such a case, will mix the colors of the highlights such that the user can easily identify the overlap and each individual highlight. (Note: in the image above, the yellowish section is actually the intersection of a green and a red highlight).
What Technology does the Selectable Highlight use?
- ReactJS
- ReactJS Functional Components
- ReactJS Hooks
- MaterialUI
- Window Web API
- Javascript
- HTML
What are the most interesting parts of Selectable Highlight?
At first glance, highlighting text seems pretty easy. But there are two intricacies that I didn't think of until I encountered them.
The first is in overlaps. How do you create highlights when they overlap? You can't just overlap span elements, because they will interfere with each other, and be ambiguous. For example, if you want to highlight "this is a highlight" such that "this is a" is in red and "is a highlight" is in yellow, we could try
<span background-color="pink">this <span background-color="yellow"> is a</span> highlight</span>
but that would result in
this is a highlight
which both doesn't highlight the right text and also doesn't mix colors. So my solution was to go through every highlight, and determine points at which we expect the highlight color to change and then create a new highlight for every one of those sections. You can read more about this and see the implementation in the repository (the GitHub wiki is also descriptive)
The second challenge in this component is determining the position of highlights. As highlights are store as starting and ending indexes in the text, our end goal for any highlight is to determine those two parameters. This is a simple application of the Window Web API if there are no preexisting highlights in the text. However, once there are existing highlights, this is a problem because you can only get text indices relative to the current node. To solve this, I keep track of and count the nodes (each representing a highlight) in a document and am able to calculate the absolute text indices from both the relative indices and the nodes they are in the context of.