How Does It Work?
Renderable
The core of Tempo is the Renderable
type. A Renderable
is a function with the following signature:
type Renderable = (context: DOMContext) => Clear
type Clear = (removeTree: boolean) => void
The Renderable
function takes a DOMContext
object, which provides access to the DOM and other utilities. The function returns a Clear
function that removes the rendered template from the DOM.
This simple signature offers flexibility and ease of use. For instance, consider the Fragment
component, which can have multiple children but doesn’t contribute to the DOM itself. It’s used to group multiple renderables together. Here’s its implementation:
export const Fragment =
(...children: TNode[]): Renderable =>
(ctx: DOMContext) => {
const clears = children.map(child => renderableOfTNode(child)(ctx))
return (removeTree: boolean) => {
clears.forEach(clear => clear(removeTree))
}
}
In Tempo, you often pass a TNode
(short for Tempo Node) to existing renderables. A TNode
is a union type that includes commonly used types in Tempo: Renderable
, Signal
, Prop
, Computed
, string
, undefined
, null
, or an Array
. The renderableOfTNode
function helps convert a TNode
to a Renderable
.
Using TNode
makes the API more flexible and allows for a more declarative syntax.
html.div('Hello World')
// equivalent to
html.div(TextNode('Hello World'))
Clear
The Clear
function removes the rendered template from the DOM. Its argument, removeTree
, indicates whether to remove all DOM modifications and side effects such as clearing an interval or timeout (true
) or only side effects (false
).
TNode
A TNode
is treated differently based on its type:
- string or
Value
(alias forSignal
): Treated as a text node.| string undefined
ornull
: Ignored.Renderable
: Left unmodified.Renderable[]
: Gets wrapped into aFragment
.
DOMContext
The DOMContext
object, passed to the Renderable function, provides access to the DOM and other utilities. It has the following properties:
element
: The Element instance associated with this context.reference
: An optional Node instance serving as a reference for this context.document
: The Document instance associated with this context.
The reference node, TextNode
with an empty string, acts as a placeholder when elements are added or removed between siblings. It’s useful for Renderables
like ForEach
or When
, which need to track element positions in the DOM.
Additionally, DOMContext
contains a collection of providers for shared state between Renderables, avoiding prop drilling and keeping the API clean. The isFirstLevel
property, still experimental, marks nodes for server-side rendering and hydration.