Last active
August 1, 2018 13:51
-
-
Save tornqvist/ff7e408ed2e13f1aad22f7ad05ac0972 to your computer and use it in GitHub Desktop.
Hypercomponent – experimental module for writing JSX-like markup with Nanocomponent
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var html = require('nanohtml') | |
var Hypercomponent = require('hypercomponent') | |
class Greeting extends Hypercomponent { | |
update (strings, ...args) { | |
return true | |
} | |
Foo (attrs, children) { | |
if (attrs.bold) children = html`<strong>${children}</strong>` | |
return html`<div>${children}</div>` | |
} | |
Bar (attrs, children) { | |
if (attrs.italic) return html`<em>${children}</em>` | |
return children | |
} | |
createElement (attrs, children) { | |
return html`<h1 ${attrs}>${children}</h1>` | |
} | |
} | |
var hello = new Greeting() | |
document.body.appendChild(hello.html` | |
<Foo bold=${true}> | |
Hello <Bar>World</Bar>! | |
</Foo> | |
`) | |
/* renders to DOM: | |
<h1> | |
<div> | |
<strong>Hello World!</strong> | |
</div> | |
</h1> | |
*/ | |
hello.html({class: 'foo'})` | |
<Foo> | |
Hello <Bar italic=${true}>World</Bar>! | |
</Foo> | |
` | |
/* re-renders as: | |
<h1 class="hello"> | |
<div> | |
Hello <em>World</em>! | |
</div> | |
</h1> | |
*/ |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var assert = require('assert') | |
var hyperx = require('hyperx') | |
var nanohtml = require('nanohtml') | |
var Component = require('nanocomponent') | |
module.exports = Hypercomponent | |
function Hypercomponent (name) { | |
Component.call(this, name) | |
var self = this | |
var createElement = this.createElement | |
var hx = hyperx(function createElement (tag, attrs, children) { | |
var keys = Object.keys(attrs) | |
for (var i = 0, len = keys.length; i < len; i++) { | |
if (!isNaN(+attrs[keys[i]])) attrs[keys[i]] = parseInt(attrs[keys[i]], 10) | |
if (attrs[keys[i]] === 'false') attrs[keys[i]] = false | |
if (attrs[keys[i]] === 'true') attrs[keys[i]] = true | |
} | |
if (tag in self) return self[tag](attrs, children) | |
if (self._hasWindow) return nanohtml.createElement(tag, attrs, children) | |
return nanohtml(['<' + tag + ' ', '>', '</' + tag + '>'], attrs, children) | |
}) | |
this._rootNodeAlias = 'Root' + (new Date() % 9e6).toString(36) | |
this[this._rootNodeAlias] = function (attrs, children) { | |
attrs = this._rootNodeAttrs || attrs | |
return createElement.call(this, attrs, children) | |
} | |
this.createElement = function (strings) { | |
var args = [] | |
for (var i = 1; i <= arguments.length; i++) args.push(arguments[i]) | |
strings = strings.slice() | |
var length = strings.length - 1 | |
strings[0] = '<' + this._rootNodeAlias + '>' + strings[0] | |
strings[length] = strings[length] + '</' + this._rootNodeAlias + '>' | |
return hx.apply(undefined, [strings].concat(args)) | |
} | |
} | |
Hypercomponent.prototype = Object.create(Component.prototype) | |
Hypercomponent.prototype.constructor = Hypercomponent | |
Hypercomponent.prototype.html = function () { | |
var args = [] | |
for (var i = 0; i < arguments.length; i++) args.push(arguments[i]) | |
assert(typeof args[0] === 'object', 'HyperComponent.html: attrs should be type object') | |
if (!Array.isArray(args[0])) { | |
this._rootNodeAttrs = args[0] | |
return this.html.bind(this) | |
} | |
var value = this.render.apply(this, args) | |
delete this._rootNodeAttrs | |
return value | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment