This is a Babel plugin that transpiles markup into hyperscript. Compatible with any hyperscript library that accepts hyperscript in the form of hyperscriptFunction(tag, attributes, [children])
. Works with React, Mithril, and Hyperapp.
Views are declared by the magic sequence $>
. This will transpile the template that follows it into hyperscript calls.
You can specify which hyperscript function to call like this:
$>
-- Transpile toReact.createElement()
.$m>
-- Transpile tom()
.$h>
-- Transpile toh()
.$yourFunc>
-- Transpile toyourFunc()
.
For example, this template:
const view = $>
(div)
(h1 > 'Contacts')
(ul)
(contacts.filter(contact => contact.email) >> contact)
(li(key=contact.key))
(h2 > contact.name)
(a(href='mailto:' + contact.email) > contact.email)
Will transpile to this code:
var view = React.createElement("div", {}, [React.createElement("h1", {}, ['Contacts']), React.createElement("ul", {}, [function () {
var t = contacts.filter(function (contact) {
return contact.email;
});
return t ? t.map(function (contact) {
return React.createElement("li", {
key: contact.key
}, [React.createElement("h2", {}, [contact.name]), React.createElement("a", {
href: 'mailto:' + contact.email
}, [contact.email])]);
}) : [];
}()])]);
Any html element can be expressed in parentheses:
(img)
CSS classes can be set using the .
operator:
(img.my-class-name.my-other-class-name)
An element id can be set with the +
operator (as # wouldn't be valid haxe syntax):
(img+my-id)
Attributes can be used inside the selector:
(img(src="img.jpg"))
Attributes can also be expressed separately:
(img(src="img.jpg", alt=""))
(img(src="img.jpg", aFunctionCallReturningAttributes()))
A component needs to have it's first letter capitialized:
(div)
(MyComponent(param=1))
(MyOtherComponent(param=2))
A shortcut for defining one child:
(h1 > 'My title')
More than one child can be nested by using indentation:
(nav)
(ul.links)
(li)
(a(href="http://haxe.org") > 'Haxe')
(li)
(a(href="http://github.com") > 'Github')
Strings and template strings are supported.
(h1)
('A string for example')
(button)
(`${this.buttonLabel}`)
Prefix an expression or identifier with the tilde operator ~
to embed an expression without a call to the hyperscript functor.
(div)
(~expression)
Would translate to:
React.createElement('div', {}, expression)
$if
, $elseif
, and $else
can be used inside templates:
($if (headerSize == 1))
(h1 > 'Big')
($elseif (headerSize == 2))
(h2 > 'Not that big')
($else)
(p > 'Paragraph')
The following syntax can be used for any object (in this case links
) with a map method:
(links => link)
(a (href=link.url, target='_blank') > link.title)
Using the >>
operator adds a null check prior to map execution.
(links >> link)
(a (href=link.url, target='_blank') > link.title)
Translates to:
if (links != null)
links.map(function(link) React.createElement('a', { href: link.url, target: '_blank' }, [ link.title ]);
else
[];
An example can be found at examples/simple
.
To build it:
cd examples/simple
npm install
npm run build
cd htdocs
see index.html