This page contains my first attempts to use Yo-Yo with Web Components. My goal is to create something that's as easy-to-use as React, but that's much more minimal and native.
hello-label
window.customElements.define('hello-label', class extends HTMLYoYo {
render() {
return yo`<div>Hello ${this.getAttribute('label')}</div>`
}
})
seconds-elapsed
window.customElements.define('seconds-elapsed', class extends HTMLYoYo {
static get observedAttributes() {
return ['tick']
}
connectedCallback() {
this.state.tick = 0
this.interval = setInterval(() => {
this.state.tick++
}, 1000)
}
disconnectedCallback() {
clearInterval(this.interval)
}
render() {
return yo`<div>Seconds Elapsed: ${this.getAttribute('tick')}</div>`
}
})
todo-app
window.customElements.define('todo-app', class extends HTMLYoYo {
constructor() {
super()
this.handleChange = this.handleChange.bind(this)
this.handleSubmit = this.handleSubmit.bind(this)
this.state.items = []
this.state.text = ''
}
static get observedAttributes() {
return ['items', 'text']
}
render() {
return yo`
<div>
<h3>TODO</h3>
<todo-list items=${this.getAttribute('items')}></todo-list>
<form onsubmit=${this.handleSubmit}>
<input onchange=${this.handleChange} value=${this.state.text} />
<button>${'Add #' + (this.state.items.length + 1)}</button>
</form>
</div>
`
}
handleChange(e) {
this.state.text = e.target.value
}
handleSubmit(e) {
e.preventDefault()
var newItem = {
text: this.state.text,
id: Date.now()
}
this.state.items = this.state.items.concat([newItem])
this.state.text = ''
}
})
window.customElements.define('todo-list', class extends ThirdBase {
constructor() {
super()
}
static get observedAttributes() {
return ['items']
}
render() {
const items = this.state.items || []
return yo`
<ul>
${items.map(item => yo`
<li key=${item.id}>${item.text}</li>
`)}
</ul>
`
}
})
markdown-editor
window.customElements.define('markdown-editor', class extends HTMLYoYo {
constructor() {
super()
this.handleChange = this.handleChange.bind(this);
this.state.value = 'Type some *markdown* here!'
}
static get observedAttributes() {
return ['value']
}
handleChange(e) {
this.state.value = e.target.value
}
getRawMarkup() {
var md = new Remarkable()
return md.render(this.state.value)
}
render() {
var el = yo`
<div class="markdown-editor">
<h3>Input</h3>
<textarea onchange=${this.handleChange}>${this.state.value}</textarea>
<h3>Output</h3>
<div class="content"></textarea>
</div>
`
el.querySelector('.content').innerHTML = this.getRawMarkup()
return el
}
})