JSFiddle - React, Tailwind, and code Playground

by Hajime Yamasaki Vukelic

CSS

* {
  margin: 0;
  padding: 0;
  font-weight: normal;
  font-size: 100%;
  list-style: none;
}

body {
  font-family: sans-serif;
  font-size: 18px;
}

strong {
  font-weight: bold;
}

.products {
  padding: 1rem;
}

.header {
  border-bottom: 1px solid black;
}

.product {
  border-bottom: 1px dashed silver;
}

.header,
.product {
  display: flex;
  justify-content: space-between;
}

.hdr,
.cell {
  display: inline-block;
  padding: 1rem;
  margin-right: 1rem;
  width: 100%;
}

.hdr {
  font-weight: bold;
  text-transform: uppercase;
}

.hdr-price {
  text-align: right;
}

.cell-id {
  background: #ffffee;
}

.cell-price {
  text-align: right;
}

.controls {
  padding: 1rem
}

.typeSelect {
  margin-right: 0.3rem;
}

.priceFilter {
  margin-right: 0.3rem;
}

Babel + JSX

/** @jsx h **/

const root = document.body


// CONSTANTS

const TYPES = [
  'shoes',
  'trousers',
  'socks',
  'skirts',
  'shirts',
  'blouses',
]


const MAKERS = [
  'Mike & Co.',
  'Farrismo',
  'Shitless',
  'Gimmedime',
  'A la ropa',
]


const CONVERSION_RATE = 1.2  // USD per EUR

const CURRENCY_SWITCH = {
  EUR: 'USD',
  USD: 'EUR',
}


// Utility functions


const forEach = (fn, arr) => {
  const l = arr.length
  for (let i = 0; i < l; i += 1) {
    fn(arr[i])
  }
}


const flatten = arr => {
  let out = []
  forEach(x => out = out.concat(x), arr)
  return out
}


const map = (fn, arr) => {
  const out = []
  forEach(x => out.push(fn(x)), arr)
  return out
}


const filter = (fn, arr) => {
  const out = []
  forEach(x => {
    if (fn(x)) {
      out.push(x)
    }
  }, arr)
  return out
}


const range = (start, end) => {
  const out = []
  for (let i = start; i <= end; i += 1) {
    out.push(i)
  }
  return out
}


const clearChildren = node => {
  node.textContent = ''
}


const replaceChildren = (childNodes, node) => {
  clearChildren(node)
  forEach(child => {
    node.appendChild(child)
  }, flatten(childNodes))
}


// Low-level support code


const h = (tag, attrs, ...children) => {
  const elm = document.createElement(tag)
  for (let key in attrs) {
    if (key === 'ref') continue
    if (key.slice(0, 2) == 'on') {
      const evtName = key.slice(2)
      const topic = attrs[key]
      if (topic == null) continue  // we can use null or undefnied to suppress
      elm.addEventListener(evtName, event => {
        pubSub.publish(topic, event)
      }, false)
    } else if (['disabled', 'autocomplete', 'selected', 'checked'].indexOf(key) > -1) {
      if (attrs[key]) {
        elm.setAttribute(key, key)
      }
    } else {
      if (attrs[key] == null) continue  // Don't set undefined or null attributes
      elm.setAttribute(key, attrs[key])
    }
  }
  if (children.length === 0) {
    return elm
  }
  forEach(child => {
    if (child instanceof...