Adds React-style prop support for Snabbdom JSX
NPM
$ npm i snabbdom snabbdom-transform-jsx-props
Add the jsxPropsModule
export to Snabbdom's init
function. It must be the first module as the JSX props will be forwarded to the appropriate Snabbdom module object.
import { classModule, styleModule } from "snabbdom"
import { jsxPropsModule } from "snabbdom-transform-jsx-props"
const patch = init([jsxPropsModule, classModule, styleModule])
The below example demonstrates the new JSX prop signature when using this module:
Vanilla 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 jsxPropsModule
:
<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>
At its core, this module forwards most props to the attributes module. Otherwise, here's what to expect:
-
key
prop is left as-is -
All module props are unaffected (to prevent regressions on vanilla behavior)
-
Some props, such as
className
ortabIndex
, are always moved to the props module to be set as DOM properties -
Shorthands (prefixed module props) can be used to direct a JSX prop into a specific module. This flattens props (useful for hooks and listeners especially). These are the supported module prefixes:
Prop pattern Module Example hook-
Hooks hook-insert={() => {}}
on-
Event handlers on-click={() => {}}
data-
Dataset data-el-id="123"
attrs-
Attributes attrs-role="region"
props-
Properties props-dir="rtl
By default, Snabbdom won't handle attributes/properties unless declared in a module object. While functional and concise, that module-driven prop signature is awkward given the prevalence of HTML-like JSX prop signatures in tools like React.
This module aims to improve that developer experience while retaining the great performance already present in Snabbdom.
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.