JSFiddle - React, Tailwind, and code Playground

HTML

<masonry-gallery></masonry-gallery>

Babel + JSX

class MasonryGallery extends HTMLElement {

	items = [
    { image:'https://unsplash.it/200/100/' },
    { image:'https://unsplash.it/200/200/' },
    { image:'https://unsplash.it/200/300/' },
    { image:'https://unsplash.it/200/400/' },
    { image:'https://unsplash.it/200/300/' },
    { image:'https://unsplash.it/200/200/' },
    { image:'https://unsplash.it/200/100/' },
    { image:'https://unsplash.it/200/300/' },
    { image:'https://unsplash.it/200/700/' },
    { image:'https://unsplash.it/200/300/' },
    { image:'https://unsplash.it/200/200/' },
    { image:'https://unsplash.it/200/600/' },
    { image:'https://unsplash.it/200/100/' }
  ]

  constructor() {
  	super()
    this.attachShadow({ mode: 'open'})
    this.create()
    this.append()
  }
  
  create() {
  	this.style.display = 'grid'
    this.style.gridTemplateColumns = 'repeat(auto-fill, 200px)'
    this.style.gridTemplateRows = 'repeat(auto-fill, 1fr)'
    this.style.gridGap = '1rem'
    this.style.gridAutoFlow = 'row dense'
  }
  
  append() {
               
  	this.items.map(item => {
    
    	const div = document.createElement('DIV');
      const image = document.createElement('IMG')
      
      image.src = item.image
      div.appendChild(image)
      
      this.shadowRoot.appendChild(div)
      
      div.style.gridRow = 'auto / span ' + [...String(image.height)][0]
    })
    
  }
   
}

customElements.define('masonry-gallery', MasonryGallery)