mirror of
https://github.com/phfroidmont/scalive.git
synced 2025-12-25 05:26:59 +01:00
Add dynamic attributes
This commit is contained in:
parent
82c0922cfa
commit
62c1a8a9f4
4 changed files with 53 additions and 3 deletions
|
|
@ -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) =>
|
||||
|
|
|
|||
|
|
@ -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")
|
||||
|
|
|
|||
|
|
@ -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(
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ object LiveViewSpec extends TestSuite:
|
|||
title: String = "title value",
|
||||
bool: Boolean = false,
|
||||
nestedTitle: String = "nested title value",
|
||||
cls: String = "text-sm",
|
||||
items: List[NestedModel] = List.empty
|
||||
)
|
||||
final case class NestedModel(name: String, age: Int)
|
||||
|
|
@ -79,6 +80,43 @@ object LiveViewSpec extends TestSuite:
|
|||
}
|
||||
}
|
||||
|
||||
test("Dynamic attribute") {
|
||||
val lv =
|
||||
LiveView(
|
||||
new View[TestModel]:
|
||||
val root: HtmlElement[TestModel] =
|
||||
div(cls := model(_.cls))
|
||||
,
|
||||
TestModel()
|
||||
)
|
||||
test("init") {
|
||||
assertEqualsJson(
|
||||
lv.fullDiff,
|
||||
Json
|
||||
.Obj(
|
||||
"s" -> Json
|
||||
.Arr(Json.Str("<div class=\""), Json.Str("\"></div>")),
|
||||
"0" -> Json.Str("text-sm")
|
||||
)
|
||||
)
|
||||
}
|
||||
test("diff no update") {
|
||||
assertEqualsJson(lv.diff, emptyDiff)
|
||||
}
|
||||
test("diff with update") {
|
||||
lv.update(TestModel(cls = "text-md"))
|
||||
assertEqualsJson(
|
||||
lv.diff,
|
||||
Json.Obj("0" -> Json.Str("text-md"))
|
||||
)
|
||||
}
|
||||
test("diff with update and no change") {
|
||||
lv.update(TestModel(cls = "text-md"))
|
||||
lv.update(TestModel(cls = "text-md"))
|
||||
assertEqualsJson(lv.diff, emptyDiff)
|
||||
}
|
||||
}
|
||||
|
||||
test("when mod") {
|
||||
val lv =
|
||||
LiveView(
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue