calmm-js / karet

Karet is a library that allows you to embed Kefir observables into React VDOM
MIT License
83 stars 8 forks source link
counterculture incremental jsx kefir observables react reactive vdom

Karet · Gitter GitHub stars npm

Karet is a library that allows you to embed Kefir properties into React Virtual DOM. Embedding observable properties into VDOM has the following benefits:

Using Karet couldn't be simpler. Usually you just import * as React from 'karet' and you are good to go.

npm version Gitter Build Status Code Coverage

Contents

Tutorial

To use Karet, you simply import it as React:

import * as React from 'karet'

and you can then write React components:

const App = () => (
  <div>
    <h1>What is the date and time</h1>
    {Kefir.interval(1000)
      .toProperty(() => {})
      .map(() => new Date().toString())}
  </div>
)

with VDOM that can have embedded Kefir properties. This works because Karet exports an enhanced version of createElement.

Note that the result, like the date and time display above, is just a React component. If you export it, you can use it just like any other React component and even in modules that do not import karet.

Here is a live example in CodeSandbox.

More links to live examples in the Calmm documentation Wiki.

Reference

React exports passed through

Karet passes through the following exports from React:

Notably the following are not exported:

karet-lift attribute

Karet only lifts built-in HTML elements and fragments implicitly. The karet-lift attribute on a non-primitive element instructs Karet to lift the element.

For example, you could write:

import Select from 'react-select'
import * as React from 'karet'

// ...

const ReactSelect1 = ({value}) => (
  <Select
    karet-lift
    name="form-field-name"
    value={value}
    options={options}
    onChange={o => value.set(o && o.value)}
  />
)

to be able to use Select from React Select with embedded Kefir Atoms.

Here is a live example in CodeSandbox.

fromClass(Component)

Karet only lifts built-in HTML elements and fragments implicitly. fromClass allows one to create lifted version of a given React component.

For example, you could write:

import Select from 'react-select'
import * as React from 'karet'

const SelectLifted = React.fromClass(Select)

const ReactSelect2 = ({value}) => (
  <SelectLifted
    name="form-field-name"
    value={value}
    options={options}
    onChange={o => value.set(o && o.value)}
  />
)

to be able to use Select from React Select with embedded Kefir Atoms.

Here is a live example in CodeSandbox.

Known gotchas

The React inline elements transform is incompatible with Karet, because it bypasses React.createElement. OTOH, the React constant elements transform works just fine with Karet.