JSFiddle - React, Tailwind, and code Playground

HTML

<script src="https://cdn.rawgit.com/davidjamesstone/brave/master/dist/brave.js"></script>
<div my-app>
  <h1 as="headingEl"></h1>
  <form my-login="userData" as="formEl">
    <input type="text">
    <input type="password">
    <button as="buttonEl">Login</button>
  </form>
  <div my-widget="widgetData" as="widgetEl"></div>
</div>

JavaScript

Brave.register({
  'my-app': {
    initialize: function () {
      this.headingEl.innerHTML = this.data.appName
    },
    showMessage: function (message) {
      alert(message)
    },
    sayHi: function () {
      this.showMessage('Hello from app')
    },
    get someProp () {
      return 'I\'m on the the app\'s prototype'
    }
  },
  'my-login': {
    initialize: function () {
      console.log('my-login')
    },
    on: {
      'submit:form': function (e) {
        e.preventDefault()
        this.login()
      }
    },
    login: function () {
      this.showMessage('Logging in...')
      this.showMessage('I can call my parent scope\'s methods and properties')
    }
  },
  'my-widget': {
    initialize: function () {
      console.log('my-widget')
    },
    template: function () {
      // This will be rendered when components are initialized.
      // Notice how child components can be created e.g. `my-widget-item`
      var str = '<ul>'
      for (var i = 0; i < this.data.length; i++) {
        str += '<li my-widget-item="[' + i + ']" as="listItem_' + i + '"></li>'
      }
      str += '</ul>'
      return str
    }
  },
  'my-widget-item': {
    initialize: function () {
      console.log('my-widget-item')
    },
    on: {
      click: function (e) {
        this.showMessage('Widget item clicked')
      }
    },
    template: function () {
      return '<a as="item_' + this.data +'" href="#">' + this.data + '</a>'
    }
  }
})

var data = {
  appName: 'My App',
  userData: {
    userName: 'Jane',
    password: 'secret'
  },
  widgetData: [1, 2, 3]
}

Brave.scan(document.body, data)