Awesome
<h1 align="center"> Snabbdom-pragma </h1> <div align="center"> Well tested <code>NotReact.createElement</code> pragma although for Snabbdom ! </div> <br/> <div align="center"> <a href="https://www.npmjs.com/package/snabbdom-pragma"> <img src="https://img.shields.io/npm/v/snabbdom-pragma.svg?label=release&style=flat-square" alt="npm version"/> </a> <a href="https://github.com/Swizz/snabbdom-pragma/blob/master/LICENSE.md"> <img src="https://img.shields.io/badge/license-MIT-blue.svg?style=flat-square" alt="mit license"/> </a> <a href="https://travis-ci.org/Swizz/snabbdom-pragm"> <img src="https://img.shields.io/travis/Swizz/snabbdom-pragma/develop.svg?style=flat-square" alt="travis build"/> </a> </div> <br/>Snabbdom-pragma is the favorite way to use the Facebook JSX syntax with the virtual DOM library Snabbdom. Based on many principles, Snabbdom-pragma, aim to handle the same API as React.createElement to take all benefits from the most used transpilers proven by the wider React community.
Snabbdom-pragma draws its strength thanks to the Snabbdom, Facebook JSX, and React.createElement specs with some grounded tests.
Table of Contents
<details> <summary>Table of Contents</summary> </details>Getting started
-
1. To use Snabbdom-pragma you need to download it thanks to your favorite JavaScript Package Manager.
yarn add snabbdom-pragma
npm install --save snabbdom-pragma
-
2. The pragma option tells to your transpiler to use
Snabbdom.createElement
function instead of the defaultReact.createElement
.buble.transform(input, { jsx: 'Snabbdom.createElement' })
-
3. You will need to import the
Snabbdom.createElement
function into your code.import Snabbdom from 'snabbdom-pragma'
-
4. Your JSX source code will now be transpiled to use Snabbdom.
const vnode = <div>Hello World</div> patch(document.body, vnode)
Usage
Snabbdom-pragma is compiler/transpiler independent ! At least your transpiler allow custom JSX pragma. (If you know a well used transpiler not in this list, feel free to open an issue)
Bublé
Snabbdom-pragma works fine and is fully tested for Bublé.
buble.transform(input, {
jsx: 'Snabbdom.createElement'
})
Typescript
Snabbdom-pragma works fine and is fully tested and typed for Typescript.
typescript.transpileModule(input, {
compilerOptions: {
jsx: 'react',
jsxFactory: 'Snabbdom.createElement'
}
})
Babel
Snabbdom-pragma works fine and is fully tested for Babel with the transform-react-jsx plugin enabled.
babel.transform(input, {
plugins: ['transform-react-jsx', {
pragma: 'Snabbdom.createElement'
}]
})
Traceur
Snabbdom-pragma works fine and is fully tested for Traceur.
traceur.compile(input, {
jsx: 'Snabbdom.createElement'
})
JSX Features
Thanks to your transpiler, JSX tags will be transpiled into NotReact.createElement
function following the React.creatElement
specifications.
Elements
As Snabbdom.createElement
is like a straightforward mapping to Snabbdom/h
, HTML elements will work out of the box.
/* written */
const vnode = <div>Hello World</div>
/* Once Transpiled */
const vnode = Snabbdom.createElement('div', null, 'Hello World')
/* Similar to */
const vnode = h('div', {}, 'Hello World')
Attributes
By default, attributes will be entrust to the props
module. (see Modules Features)
/* written */
const vnode = <input type="text"/>
/* Once Transpiled */
const vnode = Snabbdom.createElement('input', { type: 'text' })
/* Similar to */
const vnode = h('input', { props: { type: 'text' } }, [])
SVG
SVG tags work without any configuration, but attributes will only work with the attrs
module.
/* written */
const vnode = <circle cx="43.5" cy="23" r="5"/>
/* Once Transpiled */
const vnode = Snabbdom.createElement('circle', { cx: 43.5, cy: 23, r: 5 })
/* Similar to */
const vnode = h('circle', { attrs: { cx: 43.5, cy: 23, r: 5 } }, [])
Snabbdom Features
In Snabbdom, functionalities is delegated to separate modules. Like hook
(lifecycle), on
(events), style
, props
, etc...
Snabbdom-pragma give you two ways to use these modules.
Modules object
You can deal with modules properties with an object.
/* written */
const vnode = <div style={{ color: 'red', fontWeight: 'bold' }}></div>
/* Once Transpiled */
const vnode = Snabbdom.createElement('div', { style: { color: 'red', fontWeight: 'bold' } })
/* Similar to */
const vnode = h('div', { style: { color: 'red', fontWeight: 'bold' } }, [])
Modules attribute
Or by using the MODULE-PROPERTY
attribute.
/* written */
const vnode = <button on-click={ callback }/>
/* Once Transpiled */
const vnode = Snabbdom.createElement('button', { 'on-click': callback })
/* Similar to */
const vnode = h('button', { on: { click: callback } }, [])
Both
/* written */
const vnode = <div style-color="red" style={{ background: 'blue' }}></div>
/* Once Transpiled */
const vnode = Snabbdom.createElement('div', { 'style-color': 'red', style: { background: 'blue' } })
/* Similar to */
const vnode = h('div', { style: { color: 'red', background: 'blue' } }, [])
Custom Modules
Custom modules are supported through the createElementWithModules
method.
You will need to register this method as pragma instead of the createElement
.
pragma: 'Snabbdom.createElementWithModules("ALIAS_1": "MODULE_1", "ALIAS_2": "MODULE_2", ...)'
Then use
/* written */
const vnode = <div style-color="red"></div>
/* Once Transpiled */
const vnode = Snabbdom.createElementWithModules({ 'style': '' })('div', { style: { 'color': 'red' } })
/* Similar to */
const vnode = h('div', { style: { color: 'red' } }, [])
'NotReact' Features
In React you can create components and use them inside other components, using the React.createClass
function.
Components
Snabbdom-pragma use simple functions as component of type (attributes, children) => vnode
.
/* written */
const Component = ({ name }, children) =>
<div>
Hello { name }
<div>
{ children }
</div>
</div>
const vnode = <Component name="world">
<p>It works !</p>
</Component>
/* Once Transpiled */
const Component = ({ name }, children) =>
Snabbdom.createElement('div', null, 'Hello ', name,
Snabbdom.createElement('div', null, children)
)
const vnode = Snabbdom.createElement(Component, { name: 'world' },
Snabbdom.createElement('p', null, 'It works !')
)
/* Similar to */
const Component = ({ name }, children) =>
h('div', {}, ['Hello ', name,
h('div', {}, children)
])
const vnode = Component({ name: 'world' }, [
h('p', {}, 'It works !')
])
As in React, components function need to start with a capital letter, while regular HTML tags start with lower case letters. This is the common way to tell to your transpiler to give the function to the Snabbdom.createElement
instead of a string.
Misc
- Snabbdom-pragma follows the Compatible Versioning: major.minor only convention.
- Release notes are Keep a Changelog compliants.
- SVG capable thanks to @jvanbruegge PR#4
- Documentation styling have been stolen to the FlyJS project
- Some part are shameless copy of the Snabbdom-jsx documentation