I've done a basic RTE in React for a client. I've done three now and RTEs are always annoying but the difficulty in this case is largely in how you model it. I chose to create a JS object per block element (usually a paragraph) consisting of the text as a string and a set of text ranges (start/end/type). Input was via hidden text field that's updated as you change blocks and the mapping from x+y screen coordinates (click, arrow up/down across block boundaries) to text field offset is doable by writing a shim for caretPositionFromPoint.
I started with just using contentEditable but you have even more exciting cross browser issues, the output is both inconsistent between browsers and terrible, and you can't do controlled input because updating the editable content DOM at all breaks undo.
With the virtual DOM model, updates are roughly O(n) where n is the size of the virtual DOM. The way to handle very large amounts of input is to window the input data and only vdom render/diff the subset of the data that's currently visible.
How did you capture and render text input, and how did you handle new lines when the text wrapped? How do you handle paragraphs, especially when a user would delete text?
I only ask because I determined it impossible to use React for a RTE over the last year and instead opted to use Redactor/contenteditable. I just could not solve those problems easily/quickly enough to make it worth it :(
I'd be extremely curious to see any at all type of implementation for a RTE in React if you have one you could share.
> How did you capture and render text input, and how did you handle new lines when the text wrapped? How do you handle paragraphs, especially when a user would delete text?
For rendering, I had a component that rendered the block element by splitting the text string at the indicies specified by the text ranges, inserting the appropriate tags, and dangerouslySetInnerHTMLing the text. I'd probably just manually generate vDOM nodes if I were to revisit it.
I didn't do line breaking, moving up/down was done using the caretPositionFromPoint code: create range, get it's bounding box to get initial x/y, getClientRects to get the position for the next line, caretPositionFromPoint, get block text index.
In this case (I did mention it was basic) I wound up not having to do cross-block operations because the UI never had more than one. I had a plan but not having to do it makes me happy.
In conclusion, you're probably better off just using an existing RTE.
I started with just using contentEditable but you have even more exciting cross browser issues, the output is both inconsistent between browsers and terrible, and you can't do controlled input because updating the editable content DOM at all breaks undo.
With the virtual DOM model, updates are roughly O(n) where n is the size of the virtual DOM. The way to handle very large amounts of input is to window the input data and only vdom render/diff the subset of the data that's currently visible.