Zero uses normal Clojure data structures to represent markup, similar to Hiccup and Reagent.
Most values will just be stringified and rendered as TextNode
s; the exceptions
are seqs and vectors.
Seqs (including nil) will be flattened, and all children rendered inline in place
of the seq itself. This means nil
renders nothing.
Vectors usually get rendered as some kind of HTMLElement
. They should
begin with a keyword indicating the element tag.
[:div "I am a DIV"]
<div>I am a DIV</div>
Vectors can also include props (either a map or sequence of keyword-value pairs) following the initial tag:
[:div {:foo "something"} "I am a DIV"]
[:div :foo "something" "I am a DIV"]
<div foo="something">I am a DIV</div>
Props get rendered to the DOM like this: if the target element type has a matching property name (the prop name converted to cammelCase) then that property will be set to the prop value, otherwise the value will be stringified and set as an attribute on the element, with the same name as the prop.
As a convenient shorthand, an ID and classes can be included in the node's tag.
[:div#my-thing.foo.bar "I'm a DIV"]
<div id="my-thing" class="foo bar">I'm a DIV</div>
And nodes with a single child can be given as a nesting:
[[:div.foo :span.bar] :baz "something" "I'm a SPAN"]
<div class="foo"><span class="bar" baz="something">I'm a SPAN</span></div>
:root>
A vector with the special tag :root>
may be given as the top-level node of a component's
markup. This provides a node on which to attach props that apply to the component itself,
rather than one of its child elements.
Zero supports a set of props which have special meaning to the rendering
engine. These are all namespaced with z
, un-namespaced props are always treated
consistently as described above.
:zero.core/on
This prop allows event handlers to be declaratively attached to the target element.
:root>
node it attaches even handlers to the ShadowRoot, onto which the
following lifecycle events are dispatched by Zero
connect
- after the first render once a component has been connected to the documentdisconnect
- when the component is disconnected from the documentrender
- after every renderupdate
- after every render except the first[:button
::z/on {:click #(js/console.log "Clicked")}
"Click Me"]
Either keywords or strings can be used for the event name, but they shouldn't be mixed.
:zero.core/bind
This should be given as a map of prop-name -> watchable
. The watchable
will
be bound to the named prop; so when its value changes, so the prop will be updated
accordingly. If the watchable
can also be deref'd, then it'll be deref'd for
an initial value.
:zero.core/style
This prop allows an inline style for the element to be given as a map.
:root>
node, it sets the default style for the component's host element:style
prop[:button
::z/style {:cursor "pointer" :color "black"}
"I'm a BUTTON"]
<button style="cursor: pointer; color: black;">I'm a BUTTON</div>
:zero.core/class
This prop allows the class list of an element to be set as a Clojure collection.
:root>
node:class
prop[:button
::z/class ["cursor-pointer" "text-black"]
"I'm a BUTTON"]
<button class="cursor-pointer text-black">I'm a BUTTON</div>
:zero.core/css
Only applies to the :root>
node. Allows a collection of URLs
and CSSStyleSheet
instances to be set for the component. These
stylesheets will be
adopted
by the component's ShadowRoot.
:zero.core/aria
Not implemented yet. Will only apply to the :root>
node. Will allow setting default
aria properties via ElementInternals.
:zero.core/key
This prop serves the same purpose of
React's key
props.
It allows a node to be identified as rendering to the same element instance accross renders.
Due to Zero's simplified rendering algorithm, keys may not be needed as often in Zero components as in React components. Generally, unless you have a list of things that will be re-ordered and need to be rendered stably to consistent element instances; keys are probably unnecessary.
:zero.core/tag
This prop serves a similar purpose to HTTP ETags. It allows the renderer to explicitly indicate if a node has changed or not. If found on a node, Zero will only ever re-render that node when this prop changes.
This allows the component to help optimize rendering, since Zero won't need to do any comparisons
if the :zero.core/tag
indicates that nothing has changed.
In some cases tags can mess with hot reload workflows (e.g if CSS is auto-generated),
so they can be ignored in dev builds by setting the zero.config/disable-tags?
Closure
define. Here's a shadow-cljs.edn
example:
{...
:builds
{:my-build
{...
:dev {:closure-defines {zero.config/disable-tags? true}}}}}
:zero.core/opaque?
A true value for this prop tells Zero to never mess with the contents (body) of the node it's attached to. This allows the contents to be rendered in some other way without Zero getting in the way.
Can you improve this documentation?Edit on GitHub
cljdoc is a website building & hosting documentation for Clojure/Script libraries
× close