DEV Community

Konnor Rogers
Konnor Rogers

Posted on

Modifying the default toolbar in Trix

The first thing you may be tempted to do when exploring with Trix is to change the default toolbar. It's not obvious how to do this.

First instinct would say just change the innerHTML of all <trix-toolbar> elements.

This would work for most simple use cases, but what if you have a lazy-loaded turbo frame? Now you have to listen for when that frame gets loaded and then do some innerHTML replacement there.

It quickly turns into an ever-increasing ball of complexity. When searching through the Trix source code, I came across this function:

Trix.config.toolbar.getDefaultHTML()
Enter fullscreen mode Exit fullscreen mode

You can find the coffeescript source code here:

https://github.com/basecamp/trix/blob/main/src/trix/config/toolbar.coffee

On first iteration, one would think this would work if I did something like this:

import Trix from "trix"

Trix.config.toolbar.getDefaultHTML = () => `Hi there!`
Enter fullscreen mode Exit fullscreen mode

However, due to module execution and Trix registering itself and injecting the toolbar prior to the overriding of the function taking place in our script, this won't actually work.

Instead, we have to override the getDefaultHTML() function to affect all future instances of Trix, but we also have to deal with all current instances.

To do so, here's a pretty solid trimmed down way to handle this interaction:

import Trix from 'trix';
Trix.config.toolbar.getDefaultHTML = toolbarDefaultHTML;

document.addEventListener('trix-initialize', updateToolbars, { once: true });

function updateToolbars(event) {
  const toolbars = document.querySelectorAll('trix-toolbar');
  const html = Trix.config.toolbar.getDefaultHTML();
  toolbars.forEach((toolbar) => (toolbar.innerHTML = html));
}

/**
 * @see https://github.com/basecamp/trix/blob/main/src/trix/config/toolbar.coffee
 */
function toolbarDefaultHTML() {
  const { lang } = Trix.config

  return `Default HTML goes here!`
}
Enter fullscreen mode Exit fullscreen mode

To see the full demo checkout the Stackblitz to play around with it:

Or checkout the toolbar branch on this repository:

https://github.com/ParamagicDev/exploring-trix/tree/part01-changing-the-default-toolbar

That's it for part 1! In part 2 we'll look at how we can start styling Trix to make it look more like Github's markdown editor!

Top comments (2)

Collapse
 
judelawrence profile image
Jude • Edited

In chrome I'm getting an error when I try to submit the form, which I haven't been able to fix yet.

In the JS console I get:

invalid form control with name='href' is not focusable.
<input type="url" name="href" class="trix-input trix-input--dialog" placeholder="Enter a URL…" aria-label="URL" required="" data-trix-input="">
Enter fullscreen mode Exit fullscreen mode

If I remove the updateToolbars function it works OK, but the page requires a reload for the toolbar to display correctly.

When I remove the updateToolbars function the input field that is giving me errors is still there with the exact same attributes, but it doesn't cause any issues. The issue only pops up when I run the updateToolbars function.

The input field gets replaced in the DOM when the updateToolbars function runs but with the exact same element. Could this be some weird Chrome bug?

Has anyone else come across this issue?

I've removed the ability to add links in the meantime, which works, but may need to add it back at some point.

Collapse
 
rfaugusto profile image
Rafael Alberti Cantoni Augusto

Hey @judelawrence
I've came across the same thing. What I did was place this (I'm actually using jQuery for this project) in the page I'm dealing with the editor:

$('input[name="href"]').removeAttr('required');

so I don't have to disable link insertion completely but still have the editor send the data to my backend script.

Hope it helps!