mirror of
https://github.com/phfroidmont/scalive.git
synced 2025-12-25 13:36: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 static: ArraySeq[String],
|
||||||
val dynamic: ArraySeq[LiveDyn[Model]]
|
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 =
|
def update(model: Model): Unit =
|
||||||
dynamic.foreach(_.update(model))
|
dynamic.foreach(_.update(model))
|
||||||
|
|
||||||
|
|
@ -70,6 +74,8 @@ object LiveView:
|
||||||
val (attrs, children) = el.mods.partitionMap {
|
val (attrs, children) = el.mods.partitionMap {
|
||||||
case Mod.StaticAttr(attr, value) =>
|
case Mod.StaticAttr(attr, value) =>
|
||||||
Left(List(Some(s""" ${attr.name}="$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.Tag(el) => Right(buildStaticFragments(el))
|
||||||
case Mod.Text(text) => Right(List(Some(text)))
|
case Mod.Text(text) => Right(List(Some(text)))
|
||||||
case Mod.DynText[Model](_) => Right(List(None))
|
case Mod.DynText[Model](_) => Right(List(None))
|
||||||
|
|
@ -85,8 +91,10 @@ object LiveView:
|
||||||
startsUpdated: Boolean = false
|
startsUpdated: Boolean = false
|
||||||
): Seq[LiveDyn[Model]] =
|
): Seq[LiveDyn[Model]] =
|
||||||
val (attrs, children) = el.mods.partitionMap {
|
val (attrs, children) = el.mods.partitionMap {
|
||||||
case Mod.StaticAttr(_, _) => Left(List.empty)
|
|
||||||
case Mod.Text(_) => Right(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) =>
|
case Mod.Tag(el) =>
|
||||||
Right(buildDynamic(el, model, startsUpdated))
|
Right(buildDynamic(el, model, startsUpdated))
|
||||||
case Mod.DynText[Model](dynText) =>
|
case Mod.DynText[Model](dynText) =>
|
||||||
|
|
|
||||||
|
|
@ -26,6 +26,7 @@ object Dyn:
|
||||||
|
|
||||||
enum Mod[T]:
|
enum Mod[T]:
|
||||||
case StaticAttr(attr: HtmlAttr, value: String)
|
case StaticAttr(attr: HtmlAttr, value: String)
|
||||||
|
case DynAttr(attr: HtmlAttr, value: Dyn[T, String])
|
||||||
case Tag(el: HtmlElement[T])
|
case Tag(el: HtmlElement[T])
|
||||||
case Text(text: String)
|
case Text(text: String)
|
||||||
case DynText(dynText: Dyn[T, String])
|
case DynText(dynText: Dyn[T, String])
|
||||||
|
|
@ -51,5 +52,7 @@ val li = HtmlTag("li")
|
||||||
|
|
||||||
class HtmlAttr(val name: String):
|
class HtmlAttr(val name: String):
|
||||||
def :=[T](value: String): Mod.StaticAttr[T] = Mod.StaticAttr(this, value)
|
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 idAttr = HtmlAttr("id")
|
||||||
|
val cls = HtmlAttr("class")
|
||||||
|
|
|
||||||
|
|
@ -58,17 +58,18 @@ def main =
|
||||||
|
|
||||||
println("Remove all")
|
println("Remove all")
|
||||||
lv.update(
|
lv.update(
|
||||||
MyModel(List.empty)
|
MyModel(List.empty, "text-lg")
|
||||||
)
|
)
|
||||||
println(lv.diff.toJsonPretty)
|
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)
|
final case class NestedModel(name: String, age: Int)
|
||||||
|
|
||||||
object TestView extends View[MyModel]:
|
object TestView extends View[MyModel]:
|
||||||
val root: HtmlElement[MyModel] =
|
val root: HtmlElement[MyModel] =
|
||||||
div(
|
div(
|
||||||
idAttr := "42",
|
idAttr := "42",
|
||||||
|
cls := model(_.cls),
|
||||||
ul(
|
ul(
|
||||||
model.splitByIndex(_.elems)(elem =>
|
model.splitByIndex(_.elems)(elem =>
|
||||||
li(
|
li(
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,7 @@ object LiveViewSpec extends TestSuite:
|
||||||
title: String = "title value",
|
title: String = "title value",
|
||||||
bool: Boolean = false,
|
bool: Boolean = false,
|
||||||
nestedTitle: String = "nested title value",
|
nestedTitle: String = "nested title value",
|
||||||
|
cls: String = "text-sm",
|
||||||
items: List[NestedModel] = List.empty
|
items: List[NestedModel] = List.empty
|
||||||
)
|
)
|
||||||
final case class NestedModel(name: String, age: Int)
|
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") {
|
test("when mod") {
|
||||||
val lv =
|
val lv =
|
||||||
LiveView(
|
LiveView(
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue