From a942723186eed32ef475cc3f88e76f1452c679e3 Mon Sep 17 00:00:00 2001 From: davidontop Date: Sat, 21 Sep 2024 18:17:23 +0200 Subject: [PATCH] feat: Events --- .../scala/top/davidon/sfs/dom/Element.scala | 2 +- .../davidon/sfs/dom}/ReactiveRenderer.scala | 4 +-- .../davidon/sfs/dom/TriggerableValue.scala | 5 ++++ .../davidon/sfs/dom/codecs/EmptyCodec.scala | 6 ++++ .../top/davidon/sfs/dom/keys/AriaAttr.scala | 3 +- .../top/davidon/sfs/dom/keys/EventProp.scala | 30 ++++++++++++++++++- .../top/davidon/sfs/dom/keys/HtmlAttr.scala | 3 +- .../top/davidon/sfs/dom/keys/HtmlProp.scala | 3 +- .../top/davidon/sfs/dom/keys/SvgAttr.scala | 3 +- .../top/davidon/sfs/dom/mods/EventMod.scala | 6 ++++ .../davidon/sfs/dom/{ => mods}/Modifier.scala | 3 +- .../scala/top/davidon/sfs/dom/tags/Tag.scala | 4 +-- .../sfs/renderers/ClientSideRenderer.scala | 11 +++++-- 13 files changed, 69 insertions(+), 14 deletions(-) rename {sfs/src/main/scala/top/davidon/sfs/renderers => dom/src/main/scala/top/davidon/sfs/dom}/ReactiveRenderer.scala (71%) create mode 100644 dom/src/main/scala/top/davidon/sfs/dom/TriggerableValue.scala create mode 100644 dom/src/main/scala/top/davidon/sfs/dom/codecs/EmptyCodec.scala create mode 100644 dom/src/main/scala/top/davidon/sfs/dom/mods/EventMod.scala rename dom/src/main/scala/top/davidon/sfs/dom/{ => mods}/Modifier.scala (69%) diff --git a/dom/src/main/scala/top/davidon/sfs/dom/Element.scala b/dom/src/main/scala/top/davidon/sfs/dom/Element.scala index ec7c55c..a801eb0 100644 --- a/dom/src/main/scala/top/davidon/sfs/dom/Element.scala +++ b/dom/src/main/scala/top/davidon/sfs/dom/Element.scala @@ -1,6 +1,6 @@ package top.davidon.sfs.dom -import top.davidon.sfs.dom.codecs.StringCodec +import top.davidon.sfs.dom.mods.Modifier import top.davidon.sfs.dom.tags.Tag /** tag + modifiers + value */ diff --git a/sfs/src/main/scala/top/davidon/sfs/renderers/ReactiveRenderer.scala b/dom/src/main/scala/top/davidon/sfs/dom/ReactiveRenderer.scala similarity index 71% rename from sfs/src/main/scala/top/davidon/sfs/renderers/ReactiveRenderer.scala rename to dom/src/main/scala/top/davidon/sfs/dom/ReactiveRenderer.scala index 51c8df9..272a3e4 100644 --- a/sfs/src/main/scala/top/davidon/sfs/renderers/ReactiveRenderer.scala +++ b/dom/src/main/scala/top/davidon/sfs/dom/ReactiveRenderer.scala @@ -1,7 +1,7 @@ -package top.davidon.sfs.renderers +package top.davidon.sfs.dom import org.scalajs.dom -import top.davidon.sfs.dom.Modifier +import top.davidon.sfs.dom.mods.Modifier trait ReactiveRenderer { def valueFunc[F](element: dom.Element, value: F): Unit diff --git a/dom/src/main/scala/top/davidon/sfs/dom/TriggerableValue.scala b/dom/src/main/scala/top/davidon/sfs/dom/TriggerableValue.scala new file mode 100644 index 0000000..1af938d --- /dev/null +++ b/dom/src/main/scala/top/davidon/sfs/dom/TriggerableValue.scala @@ -0,0 +1,5 @@ +package top.davidon.sfs.dom + +trait TriggerableValue[T] { + def trigger[T](value: T): Unit +} diff --git a/dom/src/main/scala/top/davidon/sfs/dom/codecs/EmptyCodec.scala b/dom/src/main/scala/top/davidon/sfs/dom/codecs/EmptyCodec.scala new file mode 100644 index 0000000..4b31abf --- /dev/null +++ b/dom/src/main/scala/top/davidon/sfs/dom/codecs/EmptyCodec.scala @@ -0,0 +1,6 @@ +package top.davidon.sfs.dom.codecs + +class EmptyCodec[T] extends Codec[T, Unit] { + override def decode(domValue: Unit): T = ??? + override def encode(scalaValue: T): Unit = {} +} diff --git a/dom/src/main/scala/top/davidon/sfs/dom/keys/AriaAttr.scala b/dom/src/main/scala/top/davidon/sfs/dom/keys/AriaAttr.scala index ff0505f..2cf968a 100644 --- a/dom/src/main/scala/top/davidon/sfs/dom/keys/AriaAttr.scala +++ b/dom/src/main/scala/top/davidon/sfs/dom/keys/AriaAttr.scala @@ -1,6 +1,7 @@ package top.davidon.sfs.dom.keys import top.davidon.sfs.dom.codecs.{Codec, StringCodec} -import top.davidon.sfs.dom.{Modifier, Value} +import top.davidon.sfs.dom.Value +import top.davidon.sfs.dom.mods.Modifier class AriaAttr[V]( suffix: String, diff --git a/dom/src/main/scala/top/davidon/sfs/dom/keys/EventProp.scala b/dom/src/main/scala/top/davidon/sfs/dom/keys/EventProp.scala index 568a6fa..fd28f5d 100644 --- a/dom/src/main/scala/top/davidon/sfs/dom/keys/EventProp.scala +++ b/dom/src/main/scala/top/davidon/sfs/dom/keys/EventProp.scala @@ -1,5 +1,33 @@ package top.davidon.sfs.dom.keys import org.scalajs.dom +import top.davidon.sfs.dom.codecs.{EmptyCodec, StringAsIsCodec} +import top.davidon.sfs.dom.mods.{EventMod, Modifier} +import top.davidon.sfs.dom.{TriggerableValue, Value} -class EventProp[Event <: dom.Event](override val name: String) extends Key {} +class EventProp[E <: dom.Event](override val name: String) extends Key { + + /** Don't use with StringRenderer and ssr off/false + * @param value + * @return + */ + def :=(value: E => Unit): Modifier[EventMod[E], Unit] = { + Modifier(this, Value(EventMod(this, value), EmptyCodec())) + } + + /** Don't use with StringRenderer and ssr off/false + * @param value + * @return + */ + def :=(value: TriggerableValue[E]): Modifier[EventMod[E], Unit] = { + Modifier(this, Value(EventMod(this, value.trigger), EmptyCodec())) + } + + /** Only use with StringRenderer and ssr off/false + * @param value + * @return + */ + def :=(value: String): Modifier[String, String] = { + Modifier(this, Value(value, StringAsIsCodec)) + } +} diff --git a/dom/src/main/scala/top/davidon/sfs/dom/keys/HtmlAttr.scala b/dom/src/main/scala/top/davidon/sfs/dom/keys/HtmlAttr.scala index e754f78..db3b016 100644 --- a/dom/src/main/scala/top/davidon/sfs/dom/keys/HtmlAttr.scala +++ b/dom/src/main/scala/top/davidon/sfs/dom/keys/HtmlAttr.scala @@ -1,7 +1,8 @@ package top.davidon.sfs.dom.keys import top.davidon.sfs.dom.codecs.{Codec, StringCodec} -import top.davidon.sfs.dom.{Modifier, Value} +import top.davidon.sfs.dom.Value +import top.davidon.sfs.dom.mods.Modifier class HtmlAttr[V]( override val name: String, diff --git a/dom/src/main/scala/top/davidon/sfs/dom/keys/HtmlProp.scala b/dom/src/main/scala/top/davidon/sfs/dom/keys/HtmlProp.scala index dd27129..a88b7c8 100644 --- a/dom/src/main/scala/top/davidon/sfs/dom/keys/HtmlProp.scala +++ b/dom/src/main/scala/top/davidon/sfs/dom/keys/HtmlProp.scala @@ -1,6 +1,7 @@ package top.davidon.sfs.dom.keys import top.davidon.sfs.dom.codecs.Codec -import top.davidon.sfs.dom.{Modifier, Value} +import top.davidon.sfs.dom.Value +import top.davidon.sfs.dom.mods.Modifier class HtmlProp[V, DomV]( override val name: String, diff --git a/dom/src/main/scala/top/davidon/sfs/dom/keys/SvgAttr.scala b/dom/src/main/scala/top/davidon/sfs/dom/keys/SvgAttr.scala index 9f6719b..6d26407 100644 --- a/dom/src/main/scala/top/davidon/sfs/dom/keys/SvgAttr.scala +++ b/dom/src/main/scala/top/davidon/sfs/dom/keys/SvgAttr.scala @@ -1,6 +1,7 @@ package top.davidon.sfs.dom.keys import top.davidon.sfs.dom.codecs.{Codec, StringCodec} -import top.davidon.sfs.dom.{Modifier, Value} +import top.davidon.sfs.dom.Value +import top.davidon.sfs.dom.mods.Modifier class SvgAttr[V]( val localName: String, diff --git a/dom/src/main/scala/top/davidon/sfs/dom/mods/EventMod.scala b/dom/src/main/scala/top/davidon/sfs/dom/mods/EventMod.scala new file mode 100644 index 0000000..1d945ca --- /dev/null +++ b/dom/src/main/scala/top/davidon/sfs/dom/mods/EventMod.scala @@ -0,0 +1,6 @@ +package top.davidon.sfs.dom.mods + +import org.scalajs.dom +import top.davidon.sfs.dom.keys.EventProp + +class EventMod[E <: dom.Event](val key: EventProp[E], val value: E => Unit) {} diff --git a/dom/src/main/scala/top/davidon/sfs/dom/Modifier.scala b/dom/src/main/scala/top/davidon/sfs/dom/mods/Modifier.scala similarity index 69% rename from dom/src/main/scala/top/davidon/sfs/dom/Modifier.scala rename to dom/src/main/scala/top/davidon/sfs/dom/mods/Modifier.scala index 3673a63..c2960cb 100644 --- a/dom/src/main/scala/top/davidon/sfs/dom/Modifier.scala +++ b/dom/src/main/scala/top/davidon/sfs/dom/mods/Modifier.scala @@ -1,5 +1,6 @@ -package top.davidon.sfs.dom +package top.davidon.sfs.dom.mods +import top.davidon.sfs.dom.Value import top.davidon.sfs.dom.codecs.Codec import top.davidon.sfs.dom.keys.Key diff --git a/dom/src/main/scala/top/davidon/sfs/dom/tags/Tag.scala b/dom/src/main/scala/top/davidon/sfs/dom/tags/Tag.scala index c53333a..3be7a0a 100644 --- a/dom/src/main/scala/top/davidon/sfs/dom/tags/Tag.scala +++ b/dom/src/main/scala/top/davidon/sfs/dom/tags/Tag.scala @@ -1,8 +1,8 @@ package top.davidon.sfs.dom.tags import org.scalajs.dom -import top.davidon.sfs.dom.codecs.StringCodec -import top.davidon.sfs.dom.{Element, Modifier, Value} +import top.davidon.sfs.dom.mods.{EventMod, Modifier} +import top.davidon.sfs.dom.{Element, Value} trait Tag[+Ref <: dom.Element] { val name: String diff --git a/sfs/.js/src/main/scala/top/davidon/sfs/renderers/ClientSideRenderer.scala b/sfs/.js/src/main/scala/top/davidon/sfs/renderers/ClientSideRenderer.scala index f462c47..2f9b9b2 100644 --- a/sfs/.js/src/main/scala/top/davidon/sfs/renderers/ClientSideRenderer.scala +++ b/sfs/.js/src/main/scala/top/davidon/sfs/renderers/ClientSideRenderer.scala @@ -2,7 +2,8 @@ package top.davidon.sfs.renderers import org.scalajs.dom import top.davidon.sfs.dom.keys.{EventProp, HtmlProp} -import top.davidon.sfs.dom.{Element, Renderer, Value} +import top.davidon.sfs.dom.mods.{EventMod, Modifier} +import top.davidon.sfs.dom.{Element, ReactiveRenderer, Renderer, Value} import scala.scalajs.js @@ -19,7 +20,7 @@ class ClientSideRenderer(val root: dom.Element) override def valueFunc[F](element: dom.Element, value: F): Unit = {} override def modifierFunc[F, T]( - modifier: top.davidon.sfs.dom.Modifier[F, T], + modifier: Modifier[F, T], value: F ): Unit = {} @@ -33,7 +34,11 @@ class ClientSideRenderer(val root: dom.Element) case _: HtmlProp[?, ?] => el.asInstanceOf[js.Dynamic] .updateDynamic(m.key.name)(m.value().asInstanceOf[js.Any]) - case _: EventProp[?] => ??? + case _: EventProp[?] => + el.addEventListener( + m.key.name, + m.value.value.asInstanceOf[EventMod[?]].value + ) case _ => el.setAttribute(m.key.name, m.value().asInstanceOf[String]) }