This library allows you to embed Bacon observables into React Virtual DOM.
Usage
The prelifted classes can be accessed from the default import:
import B from "bacon.react.html"
The names of the prelifted classes are the same as in React.DOM
.
Lifted classes
A lifted class eliminates Bacon observables that appear as attributes or direct
children of the produced element. For example, using the lifted class B.div
,
you could write
<B.div>Hello observable!</B.div>
where observable
refers to a Bacon observable. The resulting div
always
shows the latest value produced by the observable.
Mount attribute
The mount
attribute on a lifted element
<B.input =/>
does the same thing as the ordinary JSX ref
attribute: JSX/React treats it as
a special case, so it had to be renamed.
Bind attribute template
The bind
attribute template
import bind from "bacon.react.html"
can be used to bind an attribute, e.g. value
or checked
, to an object with a
set
method such as a Bacon.Atom:
const settable = ...<B.input ="text" = />
bind
extends the given object, above {value: settable}
, with an onChange
attribute containing a function that copies the attribute, above value
, from
the event target to the attribute object, above settable
.
Classes attribute template
The classes
attribute template
import classes from "bacon.react.html"
offers a way to specify className
with conditional content depending on
observables. For example:
...<B.div > Not too classy?</B.div>
classes(...)
extends to an object of the form {className: string | observable}
.
Nesting
A single lifted class, like B.input
, eliminates Bacon observables only when
they are immediately contained attributes or children of the element. So, you
can safely nest lifted elements:
const checked = ...<B.div> <B.label ="likes-bacon">Bacon is tasty:</B.label> <B.input ="checkbox" ="likes-bacon" /> <B.div =><B.em>Are you sure?</B.em></B.div></B.div>
Note, however, that only those elements that immediately contain observables must be lifted, because React will choke on plain Bacon. So, the above could also have been written as:
const checked = ...<div> <label ="likes-bacon">Bacon is tasty:</label> <B.input ="checkbox" ="likes-bacon" /> <B.div =><em>Are you sure?</em></B.div></div>
For best performance this latter version is preferable.
Lifting and Patching
If you need a lifted version of a HTML class that is not already lifted, you can
use fromClass
:
import B fromClass from "bacon.react.html"...Bspecial =
There is also fromClasses
that lifts an object of classes to an object of
lifted classes. For example, given
import fromClasses from "bacon.react.html"...const L =
then L.Some
, L.Custom
and L.Classes
are lifted versions of Some
,
Custom
and Classes
.
From Bacon
fromClass
and the prelifted classes handle the cases where the class of the
element is statically known or the element is a child of some element. In case
the class of a top-most element depends on a Bacon observable, one can use
fromBacon
:
import fromBacon from "bacon.react.html"...const choice = ...
Combining properties
For notational convenience, the default import
import B from "bacon.react.html"
is also a generalized hybrid of Bacon.combineTemplate and Bacon.combineWith with .skipDuplicates(R.equals).
The meaning of B
can be described as
x1 ... xN === === ===
where
const lift = x && xconstructor === Object || xconstructor === Array ? Bacon : x
and
const combine = ...psBacon
In other words, B(fn)
effectively lifts the given function fn
to operate on
templates of observables. B(fn, x1, ..., xN)
and B(x1, ..., xN, fn)
, where
N >= 1
, is a generalization of Bacon.combineWith
where arguments are
templates of observables. Finally, duplicates are removed from the resulting
property based on deep structural equality.
That's all folks!