A Tiny Roam Tweak

We use Roam extensively at work, but as I am prone to do, I was messing with Roam’s styles to try to make them more pleasing to my eye. One thing I couldn’t style were completed todos. I use the similar OSS tool Logseq for my personal notes/journalling/capture and I find their handling of todo display much nicer.

Maybe there’s a way to get to the text from the checked input in this Roam HTML, but I couldn’t figure it out:

<span>
  <span>
    <label class="check-container">
      <input type="checkbox" checked>
      <span class="checkmark"></span>
    </label>
  </span>
  Sanity Gardening
</span>

Instead, I hacked together some javascript that updates checked todos after a new Roam page loads:

let checkmate = () => {
  var markedCheckbox = document.querySelectorAll('input[type="checkbox"]:checked');
  for (var checkbox of markedCheckbox) {
    checkbox.parentNode.parentNode.parentNode.style.textDecoration = "line-through";
    checkbox.parentNode.parentNode.parentNode.style.color = "lightgray";
  }
}
checkmate();
window.addEventListener('popstate', (event) => {
  window.setTimeout(checkmate, 1000)
});

I could probably listen for something else besides ‘popstate’ and avoid the one second wait, but the content isn’t on the page yet if I don’t use the dreaded ‘setTimeout’.

To use it, you can drag this link to your bookmarks, and click it after loading Roam:

Complete Roam Todos

Since Roam never reloads the actual web page, it should work until you reload Roam for whatever reason. I think there is a way to have embedded JavaScript execute in Roam, but I’m pretty sure it would apply to everyone on my team using the same Roam database.