Much thanks to the people who replied. I amusingly came to a solution. Hopefully this helps other people with this problem.
The concept is that I have two editable textboxes with content, and I highlight the differences between the two. Firstly, let's address the highlighting. This is straightforward. I used Squiggs's method of comparing two strings by using the following package:
https://github.com/kpdecker/jsdiff
Utilizing the Diff package, I created a function that compares the two strings and returns a result:
function compareStrings(string1, string2) {
let results = Diff.diffChars(string1, string2);
let output = "";
results.forEach((item) => {
if (item.removed) {
output += `<span style="background-color:yellow">${item.value}</span>`;
} else if (!item.added) {
output += `${item.value}`;
}
});
return output;
}
When using the Diff package, it separates the identified differences and similarities into different items. It makes working with the findings relatively easy. In the code above, the results in results are iterated over. If an item has removed set to true, it's an item in string1 that's not in string2. If added is set to true, its an item in string2 that's not in string1. If neither are set to true, it's an item in both strings. The output of my function will contain all the characters of string1. If a item has added set to true, the item is ignored. For example, if string1 is cat and string2 is bat, output will be cat but with c highlighted in yellow.
So how do I insert this highlighted text into a Material-Ui textbox? Well, I chose to go down the route of utilizing a contentEditable control. You can transform a p tag (and other tags) to an editable textbox that renders HTML. This isn't a solution that I love since it opens up the hassle of dealing with XSS, but it seems unavoidable. If anyone follows this solution, I implore you to implement client-side and server-side input sanitation to prevent XSS. The latter is especially important because client-side validation can be bypassed rather easily through various methods, such as modifying the page with inspect element or by utilizing packet crafting tools.
Here's how a contentEditable textbox looks like in HTML:
<p
id="textbox1"
className="textbox"
variant="outlined"
contentEditable={true}
/>
From here, I can assign the results of compareStrings to it:
document.getElementById("textbox1").innerHTML = htmlData
So the end result would have two contentEditable textboxes. I would have to invoke compareStrings twice and apply the results to both.
Of course, I've only detailed just the essentials to solve this problem. There's other quality of life features such as copy and paste as detailed below:
Highlight value of @material-ui/core TextField in React at specific indices