Skip to content

geotrev/snabbdom-transform-jsx-props

Repository files navigation

♻ snabbdom-transform-jsx-props

Adds React-style prop support for Snabbdom JSX


Version License CI status bundle size dependency status

Install

NPM

$ npm i snabbdom snabbdom-transform-jsx-props

Usage

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>

Features

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 or tabIndex, 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

Why

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.

Performance

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.

About

Intuitive prop syntax for Snabbdom JSX.

Resources

License

Stars

Watchers

Forks

Packages

No packages published