diff --git a/core/src/main/scala/slinky/core/ReactElementContainer.scala b/core/src/main/scala/slinky/core/ReactElementContainer.scala index 36e98c0d..185a5c17 100644 --- a/core/src/main/scala/slinky/core/ReactElementContainer.scala +++ b/core/src/main/scala/slinky/core/ReactElementContainer.scala @@ -1,8 +1,10 @@ package slinky.core import slinky.core.facade.ReactElement + import scala.collection.immutable.{Iterable, Queue} import scala.concurrent.Future +import scala.scalajs.js import scala.util.Try trait ReactElementContainer[F[_]] extends Any { self => @@ -25,6 +27,10 @@ object ReactElementContainer { override def map[A](fa: Iterable[A])(f: A => ReactElement): Iterable[ReactElement] = fa.map(f) } + @inline implicit def jsUndefOrContainer: ReactElementContainer[js.UndefOr] = new ReactElementContainer[js.UndefOr] { + override def map[A](fa: js.UndefOr[A])(f: A => ReactElement): js.UndefOr[ReactElement] = fa.map(f) + } + @inline implicit def listContainer: ReactElementContainer[List] = new ReactElementContainer[List] { override def map[A](fa: List[A])(f: A => ReactElement): List[ReactElement] = fa.map(f) } diff --git a/core/src/main/scala/slinky/core/facade/React.scala b/core/src/main/scala/slinky/core/facade/React.scala index c8f3ad81..7a88bb11 100644 --- a/core/src/main/scala/slinky/core/facade/React.scala +++ b/core/src/main/scala/slinky/core/facade/React.scala @@ -9,7 +9,6 @@ import scala.annotation.unchecked.uncheckedVariance import scala.scalajs.js.annotation.{JSImport, JSName} import scala.scalajs.js.JSConverters._ import scala.language.implicitConversions -import scala.util.{Failure, Success, Try} @js.native trait ReactElement extends js.Object with ReactElementMod @@ -47,6 +46,12 @@ object ReactElement { } } + @inline implicit def jsUndefOrToElement[E](j: js.UndefOr[E])(implicit cv: E => ReactElement): ReactElement = { + val x = if (j.isDefined) cv(j.get) else null.asInstanceOf[ReactElement] + println(x) + x + } + @inline implicit def anyToElementContainer[E, F[_]](e: F[E])(implicit f: ReactElementContainer[F], cv: E => ReactElement): F[ReactElement] = { f.map(e)(cv) } diff --git a/tests/src/test/scala/slinky/core/annotations/ReactAnnotatedComponentTest.scala b/tests/src/test/scala/slinky/core/annotations/ReactAnnotatedComponentTest.scala index 419cc64d..42568cde 100644 --- a/tests/src/test/scala/slinky/core/annotations/ReactAnnotatedComponentTest.scala +++ b/tests/src/test/scala/slinky/core/annotations/ReactAnnotatedComponentTest.scala @@ -219,6 +219,7 @@ object DerivedStateComponent { case class Props(seq: Seq[ReactElement], list: List[ReactElement], option: Option[ReactElement], + jsUndefOr: js.UndefOr[String], attempt: Try[ReactElement], function: () => ReactElement, fragment: ReactElement, @@ -226,7 +227,7 @@ object DerivedStateComponent { varargs: ReactElement*) override def render(): ReactElement = { - div(props.seq, props.list, props.option, props.fragment, props.varargs) + div(props.seq, props.list, props.option, props.jsUndefOr, props.fragment, props.varargs) } } @@ -240,13 +241,14 @@ object DerivedStateComponent { val s = Seq("a", "b") val l = List("c", "d") val o = Some("e") - val t = Try(h2("f")) - val fn = () => "g" - val fr = Fragment(List(h1("h"), i("i"))) - val f = Future { "j" } - val v = "k" + val j = "f" + val t = Try(h2("g")) + val fn = () => "h" + val fr = Fragment(List(h1("i"), i("j"))) + val f = Future { "k" } + val v = "l" - SubComponentWithReactElementContainers(s, l, o, t, fn, fr, f, v) + SubComponentWithReactElementContainers(s, l, o, j, t, fn, fr, f, v) } } @@ -261,11 +263,12 @@ object DerivedStateComponent { Seq("a", "b"), List("c", "d"), Some("e"), - Try(h2("f")), - () => "g", - Fragment(List(h1("h"), i("i"))), - Future { "j" }, - "k" + "f", + Try(h2("g")), + () => "h", + Fragment(List(h1("i"), i("j"))), + Future { "k" }, + "l" ) } } @@ -413,7 +416,7 @@ class ReactAnnotatedComponentTest extends AsyncFunSuite { ComponentWithVariableReactElementContainers(), targetNode ) - assert(targetNode.innerHTML == "
abcde

h

ik
") + assert(targetNode.innerHTML == "
abcdef

i

jl
") } test("Can use inline ReactElementContainer types within components") { @@ -422,6 +425,6 @@ class ReactAnnotatedComponentTest extends AsyncFunSuite { ComponentWithInlineReactElementContainers(), targetNode ) - assert(targetNode.innerHTML == "
abcde

h

ik
") + assert(targetNode.innerHTML == "
abcdef

i

jl
") } } \ No newline at end of file