backstitch! š§µ

To sew with overlapping stitches, to bind two pieces of fabric together.
backstitch
allows you to wrap your React UI elements in a Web Components custom elements API, and use them in places where it's otherwise tricky to embed React ā e.g. in Elm!
API
backstitch.define
The backstitch.define
function mimics the native customElements.define
API:
backstitch.define("x-element", ReactComponent)
backstitch.props
backstitch.props
serialises plain-old-javascript props to a JSON string under the correct data-props
object key, so that they can be directly passed to a backstitch
custom element.
With the right cocktail of polyfills, this can be used to check custom elements against their original tests, e.g.:
const container = render(
React.createElement("x-element", backstitch.props(plainOldJavascriptProps))
)
backstitch.PROPS_ATTRIBUTE
The name of the props data-*
attribute (i.e. "data-props"
).
React example
import * as backstitch from "backstitch"
import ReactButton from "./components/Button"
backstitch.define("x-button", ReactButton)
const ContrivedExample = props => (
<x-button
data-props=`{"size": "huge", "blink": ${props.isObnoxious}}`
onClick={() => window.alert("Zap! Kapow!")}
>
Click Me!
</x-button>
)
Elm example
import * as backstitch from "backstitch"
import ReactButton from "./components/Button"
backstitch.define("x-button", ReactButton)
const { Elm } = require("./App.elm")
Elm.Main.init({
node: document.getElementById("root")
})
...
view : Model -> Html Msg
view model =
let
props =
encode 0 <|
object
[ ( "size", string "huge" )
, ( "blink" , bool model.isObnoxious )
]
in
Html.node "x-button"
[ attribute "data-props" props
, onClick ZapKapow
]
[ Html.text "Click Me!"
]
How it works (WIP)
On creation, the custom element creates a shadow DOM containing a single span
element. It renders a bridging React component into this element, which hosts the wrapped component and supplies its props.
The custom element listens for changes on its data-props
attribute. When it detects a change, it passes the attribute data to the bridge component, instructing it to update its state with the new data.
React then takes over and decides whether any of the wrapped components' props are affected by the new state in the bridge component. If so, this triggers a rerender of the wrapped component.
For more detail, see: ./packages/backstitch/src/custom-element.ts
Limitations
backstitch
is only able to send props data which can be serialised to JSON. While in practice this covers many use cases, some React tricks such as passing event handlers or render functions as props will not work with custom elements.