Open Source Docs

Avocet

Fast HTML template engine and eDSL for Scala 3

Virtual DOM Middleware

Scala.js DOM backend and virtual-DOM-like rendering


As a virtual DOM

Avocet can be used as virtual-DOM-like middleware. Unlike other popular virtual DOM solutions, Avocet doesn't allocate additional memory for construction of a new virtual DOM copy. Also it does not allocate memory in changes inferring phase. Avocet's memory usage is constant.

// build.sbt
libraryDependencies += "com.natural-transformation" %%% "avocet-dom" % "1.0.0"
// In your code
import org.scalajs.dom._
import avocet.dom.render
import avocet.dom.event
import avocet.dsl._
import html._

case class Todo(id: String, text: String, done: Boolean)

def onSubmitClick() = {
  val input = document
    .getElementById("todo-input")
    .asInstanceOf[html.Input]
  val inputText = input.value
  // Reset input
  input.value = ""
  val newTodo = Todo(
    id = Random.alphanumeric.take(5).mkString,
    text = inputText,
    done = false
  )
  renderTodos(todos :+ newTodo)
}

def onTodoClick(todo: Todo) = {
  renderTodos(
    todos.updated(
      todos.indexOf(todo),
      todo.copy(done = !todo.done)
    )
  )
}

def renderTodos(todos: Seq[Todo]): Unit = render(document.body) {
  optimize {
    body(
      div(clazz := "title", "Todos"),
      ul(clazz := "list",
        todos map { todo =>
          li(
            todo match {
              case Todo(_, text, true) => strike(text)
              case Todo(_, text, false) => span(text)
            },
            event("click")(onTodoClick(todo))
          )
        }
      ),
      input(id := "todo-input", placeholder := "New ToDo"),
      button("Submit", event("click")(onSubmitClick()))
    )
  }
}

val todos = Seq(
  Todo("1", "Start use Avocet", done = false),
  Todo("2", "Lean back and have rest", done = false)
)

renderTodos(todos)