-
Notifications
You must be signed in to change notification settings - Fork 27
User Interface Spec
User interface libraries based on freactive understand some variant of Hiccup-style syntax. This was chosen because it provides a fairly simple representation of a "virtual node" that works with any number of node types (as opposed to a factory-function based models that require a function for each known node).
A "virtual node" is represented by a vector whose first element is a keyword, as in Hiccup, is a keyword representing the node type with optional CSS-like shortcuts for id and class attributes where they are available. Examples: :text
, :text#my-text.a-style
. Node type keywords can be namespace prefixed if that makes sense for the underlying UI framework.
If the second element of the vector is a map, it should be treated as a map of attributes with keyword keys. Any attribute keys beginning with :on-
should be treated as events which take a Clojure function as an event handler and optionally core.async
channels into which the events will be put!
. Other attributes values can either be literal values or instances of IDeref
(such as a reactive atom
, rx
, etc.). If an instance of IDeref
is passed in as an attribute value, the underlying UI framework will attempt to attach an invalidation watch or watch to the underlying ref and update the node's attribute when the ref changes.
Example:
(ns test1
(:refer-clojure :exclude [atom])
(:require [freactive.core :refer [atom rx]]))
(defn create-elem []
(let [clicked (atom 0)]
[:button {:on-click (fn [e] (swap! clicked inc)) :text (rx (str @clicked))}])
(my-ui-framework/show (create-elem))
The remaining elements of the vector will be treated as children of the node. Child elements can be one of
- literal values (such as text strings) appropriate for the given node
- nodes themselves
- vectors representing nodes (beginning with a keyword)
- sequences of other nodes (for easy composition)
- instances of
IDeref
which should be handled as reactive nodes by the underlying framework