Skip to content

'NotReact.createElement' jsx pragma although for snabbdom

License

Notifications You must be signed in to change notification settings

Swizz/snabbdom-pragma

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Snabbdom-pragma

Well tested NotReact.createElement pragma although for Snabbdom !


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

Table of Contents

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 default React.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