Skip to content

dfadev/hyperscript-markup

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

11 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

hyperscript-markup

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.

Template Syntax

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 to React.createElement().
  • $m> -- Transpile to m().
  • $h> -- Transpile to h().
  • $yourFunc> -- Transpile to yourFunc().

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])]);
	}) : [];
}()])]);

Elements

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))

Children

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')

Inline expressions

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)

Conditionals

$if, $elseif, and $else can be used inside templates:

($if (headerSize == 1))
	(h1 > 'Big')
($elseif (headerSize == 2))
	(h2 > 'Not that big')
($else)
	(p > 'Paragraph')

Map

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)

Map with null check

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
	[];

Sample

An example can be found at examples/simple.

To build it:

cd examples/simple
npm install
npm run build
cd htdocs
see index.html

About

Babel plugin that transpiles markup into hyperscript.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published