Trix is a great text editor, but for the sake of keeping it simple and enjoyable to use, has some limitations.
One of those limitations is the lack of support for HTML tables. Paste a table in Trix, and gone is the table.
For most use cases, it isn’t too much of an issue since I feel that most of the time, it’s possible to find an alternative to a table. Sometimes in the name of simplicity it’s even good to get rid of a table.
When working on the initial version of Sequence (Timelapse at the time), I was well aware of Trix’s limitations, but the benefits and cleanliness of the library won over feature limitation.
But down the road, it became clear that for a good majority of people maintaining help centers and knowledge bases, tables were important. It’s safe to ignore a request once or twice if it doesn’t fit your product’s vision, but getting enough of the same request over and over makes you rethink the vision.
It turns out tables are important for our customers, so if it’s important for our customers, it matters to us too.
Changing the editor wasn’t an option. Just the thought of re-evaluating the hundreds of text editors out there makes me sick. And I’m already tired just thinking about the migration process. Plus, Trix is great, there’s a reason why we picked it.
So, how were we going to pull this off?
Extending Trix and adding support for tables right into its core is an option, but the lack of feedback from the maintainers of the project on GitHub when it comes to requests around table support makes me think they probably never will support tables. And I’m perfectly fine with that, I think it does go against Trix’s core principles. So, no point of extending the core and submit a pull request if it’s never going to be merged. And maintaining an independent fork of Trix isn’t an option either.
Tables as Attachments to the Rescue
A core concept of Trix is that whatever you write or paste in the editor gets converted to its internal document model. There’s no way around that, everything gets sanitized as a result.
There’s an exception though. You can basically package whatever you want into a Trix Attachment. Trix attachments were built primarily for files and images, but we use attachments for other things like embedding YouTube videos.
As long as it fits inside a
<figure> tag, it’s good for an attachment. So why not package tables inside attachments?
Plus, conceptually, tables as attachments makes sense. If you want to be able to edit tables right into Trix, it inevitably makes the editor more complex. But editing them as attachments opens the door to having a separate UI just for that, independent of Trix.
I kind of like that. And that’s what we ended up doing.
Here’s how a table looks like within our editor:
It just looks like any other attachment. In order to highlight the table icon in the editor, we had to write some code to detect the attachment type, but it’s working pretty well overall without too much customization on that front.
Clicking the Table icon in the toolbar triggers a popup with our actual Table editor. That’s where it starts to get interesting.
Meet the Table Editor
The table editor is something we’ve built from scratch and is voluntarily pretty basic. As you can see, nothing fancy. A few formatting options and controls to toggle the heading row and add or remove rows/columns.
I’m about to go real meta here, but the core idea is that we use Trix to edit individual cells’ content. Trix within Trix!
For every cell, there’s a Trix editor. Performance-wise, is this the best thing? Probably not, but our customers don’t need tables with hundreds of cells so it doesn’t really matter. We’re not trying to build another version of Excel.
The real benefit is that the editing interface remains familiar and that we don’t have to write a whole new text editor just for tables. Trix is already pretty good at formatting and sanitizing content, so we continue to offload that task to the library. All we have to handle is the actual table.
One of the main challenges was to have just one toolbar. For every Trix editor instantiated, a toolbar gets instantiated too, but we want to give the feeling that there’s just one toolbar.
We ended up hiding all toolbars and showing just the one associated with the active (focused) cell. It’s actually a little tricky since the toolbar is not right next to the input element (cell), as intended by Trix. To do so, we use the convenient jQuery (“omg, you still use jQuery?”) method detatch() to move the toolbars around.
Finally, when clicking Update, we just loop through each cell to get its content from Trix, package the table in a TrixAttachment and insert it into the editor.
Conceptually, that’s about it.
I may write a follow-up article with some code examples, but if you were looking for a way to add support for tables within Trix, you now know that it’s possible. And you know how to get going.