Adds React-style prop support for Snabbdom JSX
NPM
$ npm i snabbdom snabbdom-transform-jsx-props
Add the jsxDomPropsModule
export to snabbdom's init
function. It must be the first module.
import { classModule, styleModule } from "snabbdom"
import { jsxDomPropsModule } from "snabbdom-transform-jsx-props"
const patch = init([jsxDomPropsModule, classModule, styleModule])
This module is intended for web-related use-cases when paired with the Snabbdom package. This means non-web environments, like mobile apps and the like, are not guaranteed to work.
The below example demonstrates the new JSX prop signature when using this module:
Vanilla Snabbdom JSX:
<div props={{ className: "my-component" }} hook={{ insert: () => {} }}>
<h1 dataset={{ fooHeading: true }}>Hello world</h1>
<p attrs={{ "aria-hidden": "true" }}>And good day</p>
<a
attrs={{ href: "#", style: "color: blue" }}
props={{ tabIndex: 0 }}
on={{ click: () => {} }}
>
Try me!
</a>
</div>
With this package:
<div className="my-component" hook-insert={() => {}}>
<h1 data-foo-heading={true}>Hello world</h1>
<p aria-hidden="true">And good day</p>
<a href="#" attr-style="color: blue" tabIndex="0" on-click={() => {}}></a>
</div>
The key difference is you will no longer need a module object to add props. They are automatically added for you (unless you specify the module with a prefix), plus property/attribute props fall back to DOM attributes by default.
Specifying a Snabbdom module will direct this plugin on how to use the prop.
Prop pattern | Module | Example |
---|---|---|
hook- |
Hooks | hook-insert={fn} |
on- |
Event handlers | on-click={fn} |
data- |
Dataset | data-foo-bar={value} |
attr- |
Attributes | attr-role={value} |
prop- |
Properties | prop-dir={value} |
These are alternate names for common props. They are always treated as DOM properties, which reflect to their respective attributes.
Prop pattern | Alias for | Example |
---|---|---|
className |
className={value} |
|
class-name |
className |
class-name={value} |
tabIndex |
tabIndex={value} |
|
tabindex |
tabIndex |
tabindex={value} |
tab-index |
tabIndex |
tab-index={value} |
By default, Snabbdom jsx
pragma doesn't handle any prop not declared it in a module.
While functional and concise, this module-driven prop signature is awkward given the prevalent of HTML-like JSX prop signatures.
Like Snabbdom itself, a top priority of this module is performance. As a result, it runs linearly by detecting modules present in a given vnode, then going over the props themselves. This allows specific application of certain props to their appropriate module, then immediately iterating to the next prop.
Like all code, I wouldn't claim this to be perfect, so contributions are welcome if you suspect improvements can be made.