I’ve made a layout manager that can display rows of cells of contenteditables, although one row’s contenteditable’s height doesn’t yet affect the following rows.
While trying to navigate between contenteditables I made some of them multiline and it turns out my approach to navigating between these contenteditables was based on a single-line way of thinking about it, and the multiline approach is quite different so I had to change the approach entirely.
I naively thought the correct behaviour was about checking whether the caret position was along an edge (top/right/bottom/left) of the contenteditable and then if they press an arrow key to go beyond that then they should navigate to an adjacent contenteditable. And that makes sense for single-line contenteditables, but not for multiline. In multiline there’s quite different behaviour for vertical and horizontal caret movements due to line wrapping and how users expect to press left or right to move the caret all the way from the first letter on the top-right — to the last letter on the bottom right. The first and last letters are the only places horizontal navigation should occur. So horizontal only has those two spots that allow exiting the contenteditable, but for vertical navigation however they get a full text line. So pressing up anywhere on the first line should navigate, and pressing down on the last line should navigate.
So the correct behaviour I’m really trying to write code for is…
- top-most: whether the caret is on line 1 (because they can’t go up further)
- bottom-most: whether the caret is on the last line (because they can’t go down further)
- left-most: the horizontal axis has more complicated rules due to caret wrapping… left-most is whether the caret is on line 1 index 0 (because they can’t go left further)
- right-most: whether the caret is on the last line at the last index (because they can’t go right further)
Once I understood that I came up with a nice approach after a few days thinking about it.