Quick Start
Tempo can be used for fully fledged single-page applications or simple widgets. Either way, it is easy to get started:
- Define a template or component
- Render it to the DOM at a specific location
Hello World
A classic “Hello World” example:
import { html, render } from '@tempots/dom'
// Define a template or renderable
const HelloWorld = html.h1('Hello World')
// Render it to the DOM
render(HelloWorld, document.body)
The render()
call returns a function that can be used to remove the rendered template from the DOM:
// Render it to the DOM
const remove = render(HelloWorld, document.body)
// Remove it from the DOM after 1 second
setTimeout(() => {
console.log('Removing HelloWorld')
remove()
}, 1000)
Add state and interactivity
State in Tempo is managed through signals. Signals are reactive and can be used to update the DOM (or anything else) when they change. A Signal
is a readonly object that can be observed but not updated. A Prop
is a writable object that can be updated. A Computed
is a readonly object that is derived from other signals.
Here is an example of a simple counter:
import { html, on, render, makeProp } from '@tempots/dom'
// Define a writeable signal
const count = makeProp(0)
// Define a template
const Counter = html.div(
html.h1(count.map(v => `count: ${v}`)),
html.div(
html.button(on.click(() => count.value++), '+'),
html.button(on.click(() => count.value--), '-'),
)
)
// Render it to the DOM
render(Counter, document.body)
The count
signal is updated by mutating the count.value
that computes a new value based on the current value. count
can also be set directly by calling count.set()
or update with a function with count.update(v => v+1)
.
What about count.map(v => `count: ${v}`)
? This is a Computed
signal that is derived from the count
signal. It will update whenever count
changes. The map()
function is a helper function that maps the value of the signal to a new value.
Events are handled by using the functions associated to the on
object. The on.click()
function creates an event listener for the click
event.
Note that differently from other frameworks, Tempo does not make a distinction between children nodes, attributes, properties, or event handlers. Everything satisfies the same Renderable
type and Renderable
s can be nested in any component that accept children. This brings a lot of flexibility and simplicity to the API. One exmaple is that you can use the Portal
component not just to render the content of a selected element but also change/add to its attributes, classes and event handlers.
Next Steps
- Installation
- Learn more about how Tempo works
- Renderables, the building blocks of Tempo applications
- Signals, the reactive core of Tempo
- Learn more about Building your own Renderables
- Render, the function to apply Renderables to the DOM