How to nest selectors in Mithril.js for extra brevity

Published on in JavaScript and Mithril.js

Last updated on

m.nest('ul > li', 'Item') can be achieved with reduceRight().

m.nest = (selector, ...args) => {
  const tags = selector.split('>')
  const innermost = m(tags.pop().trim(), ...args)
  return tags.reduceRight((child, tag) => m(tag.trim(), child), innermost)
}

// Usage:
m.nest('ul.foo > li.bar > a[target=_blank]', { href }, 'Link')

// The same as:
m('ul.foo', m('li.bar', m('a[target=_blank]', { href }, 'Link')))

// Output in both cases:
<ul class="foo">
  <li class="bar">
    <a target="_blank" href="...">Link</a>
  </li>
</ul>

Test the code on flems.io

Benefits:

  • cleaner
  • clearer
  • cooler!

Source

Original code on GitHub, by fuzetsu (Daniel Loomer). Variables renamed on this page for clarity.

Earlier version on Mithril's Gitter room, also by fuzetsu. Here the array is looped twice (map() + reduceRight()), whereas in the newer version (on this page) there's only one loop (reduceRight()).