Add dynamic attributes

This commit is contained in:
Paul-Henri Froidmont 2025-08-15 01:04:01 +02:00
parent 82c0922cfa
commit 62c1a8a9f4
Signed by: phfroidmont
GPG key ID: BE948AFD7E7873BE
4 changed files with 53 additions and 3 deletions

View file

@ -8,6 +8,10 @@ class LiveView[Model] private (
val static: ArraySeq[String],
val dynamic: ArraySeq[LiveDyn[Model]]
):
assert(
static.size == dynamic.size + 1,
s"Static size : ${static.size}, Dynamic size : ${dynamic.size}"
)
def update(model: Model): Unit =
dynamic.foreach(_.update(model))
@ -70,6 +74,8 @@ object LiveView:
val (attrs, children) = el.mods.partitionMap {
case Mod.StaticAttr(attr, value) =>
Left(List(Some(s""" ${attr.name}="$value"""")))
case Mod.DynAttr(attr, _) =>
Left(List(Some(s""" ${attr.name}=""""), None, Some('"'.toString)))
case Mod.Tag(el) => Right(buildStaticFragments(el))
case Mod.Text(text) => Right(List(Some(text)))
case Mod.DynText[Model](_) => Right(List(None))
@ -85,8 +91,10 @@ object LiveView:
startsUpdated: Boolean = false
): Seq[LiveDyn[Model]] =
val (attrs, children) = el.mods.partitionMap {
case Mod.StaticAttr(_, _) => Left(List.empty)
case Mod.Text(_) => Right(List.empty)
case Mod.StaticAttr(_, _) => Left(List.empty)
case Mod.DynAttr(_, value) =>
Right(List(LiveDyn.Value(value, model, startsUpdated)))
case Mod.Tag(el) =>
Right(buildDynamic(el, model, startsUpdated))
case Mod.DynText[Model](dynText) =>

View file

@ -26,6 +26,7 @@ object Dyn:
enum Mod[T]:
case StaticAttr(attr: HtmlAttr, value: String)
case DynAttr(attr: HtmlAttr, value: Dyn[T, String])
case Tag(el: HtmlElement[T])
case Text(text: String)
case DynText(dynText: Dyn[T, String])
@ -51,5 +52,7 @@ val li = HtmlTag("li")
class HtmlAttr(val name: String):
def :=[T](value: String): Mod.StaticAttr[T] = Mod.StaticAttr(this, value)
def :=[T](value: Dyn[T, String]): Mod.DynAttr[T] = Mod.DynAttr(this, value)
val idAttr = HtmlAttr("id")
val cls = HtmlAttr("class")

View file

@ -58,17 +58,18 @@ def main =
println("Remove all")
lv.update(
MyModel(List.empty)
MyModel(List.empty, "text-lg")
)
println(lv.diff.toJsonPretty)
final case class MyModel(elems: List[NestedModel])
final case class MyModel(elems: List[NestedModel], cls: String = "text-xs")
final case class NestedModel(name: String, age: Int)
object TestView extends View[MyModel]:
val root: HtmlElement[MyModel] =
div(
idAttr := "42",
cls := model(_.cls),
ul(
model.splitByIndex(_.elems)(elem =>
li(