.dom is a tiny (512 byte) template engine that uses virtual DOM and some of react principles
The major highlights of this release is the support of keyed updates, JSX and raw elements. To compensate, the support of returning raw HTML elements in place of VDom elements has been deprecated.
Features included:
React's createElement
(as H
) and ReactDOM render
(as R
):
R(H('div', 'Hello world'), document.body);
Tag shorthands via H
deconstructuring:
const { div, span, button } = H;
Class shorthands when using the tags:
R(div.someClass.anotherClass("Hello world"), document.body);
Stateless components
const Greeter = (props) =>
H('div', `Hello ${props.name}`)
R(H(Greeter, {name: "John"}), document.body);
Stateful components
const Clicker = (props, state, setState) =>
H('button', {
onClick() {
setState({ clicks: (state.clicks || 0) + 1);
}
}, `I am clicked ${state.clicks || 0} times`)
R(H(Clicker), document.body);
Component lifecycle methods
const LifecycleAware = (props, state, setState, hooks) => {
hooks.m.push(() => { setState({ mounted: "yes" }); });
return H('div', `mounted=${state.mounted || "no"}`);
}
R(H(LifecycleAware), document.body);
Higher-order components
const Greeter = (props) =>
H('div', `Hello ${props.name}`)
const NameBob = (wrappedComponent) => (props) =>
H(wrappedComponent, {name: "bob"})
R(H(NameBob(Greeter)), document.body);
NEW! VNode state now carried in the VDom instance
function Component(state) {
if (!state.elm) state.elm = H("div", "Keyed");
return H("div", state.elm);
}
NEW! Unreconcilable node support (raw nodes)
function RawElement(state, _, _, hooks) {
hooks.r = 1; // Enable raw mode
return H("div", {
innerHTML: "<p>Raw HTML</p>"
});
}
NEW! Keyed updates (via the keyed
plugin)
function MyComponent(props, state) {
const { values } = props;
const components = values.map(value => {
H(ValueRenderer, {
key: value,
value: value
});
})
// Synchronize state of components, based on their key
return H('div', K(state, components))
}
keyed
plugin, that can be used to enable keyed updates.H()
in order to accept null
as properties.const ComplexThing = (props, state, setState, hooks) => {
// Called when the component is mounted, passing the DOM element as argument
hooks.m.push(containerElement => {
FancyEditor.initialize(containerElement);
});
// Called when the component is unmounted
hooks.u.push(containerElement => {
FancyEditor.deinitilize(containerElement);
});
return H('div');
}
R(H(ComplexThing), document.body);
This is the first public release with most of the ideal features included. This API version is fully compatible with the 0.2.2 version of the library.
Features included:
React's createElement
(as H
) and ReactDOM render
(as R
):
R(H('div', 'Hello world'), document.body);
Tag shorthands via H
deconstructuring:
const { div, span, button } = H;
Class shorthands when using the tags:
R(div.someClass.anotherClass("Hello world"), document.body);
Stateless components
const Greeter = (props) =>
H('div', `Hello ${props.name}`)
R(H(Greeter, {name: "John"}), document.body);
Stateful components
const Clicker = (props, state, setState) =>
H('button', {
onClick() {
setState({ clicks: (state.clicks || 0) + 1);
}
}, `I am clicked ${state.clicks || 0} times`)
R(H(Clicker), document.body);
NEW! Component lifecycle methods
const LifecycleAware = (props, state, setState, hooks) => {
hooks.m.push(() => { setState({ mounted: "yes" }); });
return H('div', `mounted=${state.mounted || "no"}`);
}
R(H(LifecycleAware), document.body);
NEW! Higher-order components
const Greeter = (props) =>
H('div', `Hello ${props.name}`)
const NameBob = (wrappedComponent) => (props) =>
H(wrappedComponent, {name: "bob"})
R(H(NameBob(Greeter)), document.body);
NEW! Raw DOM Nodes as Virtual Nodes
const ComplexThing = () => {
const container = document.createElement('div');
FancyEditor.initialize(container);
return container;
}
R(H(ComplexThing), document.body);
mount
, unmount
and update
) via the hooks
fourth argument on the components.gulp-uglify-es
(with terser
) instead of the harmony branch of uglify-2.0
for the build script. This reduces the compressed archive even more, giving more room for features.$
as the key differentiator of virtual DOM nodes. It is now prohibited to use this key as property name.In this release most of the major issues have been addressed and the core API is stabilised.
ADDED: Not updating DOM properties if they are already the same. This fixes an issue with the <input />
elements not being updated properly.
ADDED: NPM-glue script for properly importing dot-dom
from npm.
ADDED: Correctly passing-through the createElement
function properties and methods through the Proxy
. This fixes an issue with H.apply
.
ADDED: Support for shallow arrays as H
children. For example:
H('div', 'foo', ['bar', 'baz'])
// .. is the same as ...
H('div', 'foo', 'bar', 'baz')
.C
from being applied as property to the DOM element. This saves a few bytes and having this extra property in the DOM element instance is not really affecting any visual behaviour.Starting from this release, the pre-defined set of HTML tags is now removed. You will now have to manually specify the tags you are going to use, by extracting them from H
. For example:
// v0.1.0
R(div('Hello world'), document.body);
// v0.2.1
const {div} = H;
R(div('Hello world'), document.body);
First alpha release