From 76665376ea37a7447a23e2a537ad938deea3a0d4 Mon Sep 17 00:00:00 2001 From: Shadaj Laddad Date: Thu, 28 Dec 2017 19:54:09 -0800 Subject: [PATCH] Add support for all possible ReactElement types in React 16 (#83) --- CHANGELOG.md | 1 + .../me/shadaj/slinky/core/facade/React.scala | 16 ++++++ .../core/ComponentReturnTypeTests.scala | 50 +++++++++++++++++++ 3 files changed, 67 insertions(+) create mode 100644 tests/src/test/scala/me/shadaj/slinky/core/ComponentReturnTypeTests.scala diff --git a/CHANGELOG.md b/CHANGELOG.md index de0b72c1..bdb5161c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,7 @@ + **BREAKING**: Stateless components that use the `@react` macro annotation must extend the `StatelessComponent` class instead of just `Component` [PR #69](https://github.com/shadaj/slinky/pull/69) + **BREAKING**: Callbacks passed to `setState` are now Scala functions, so there is no need to force implicit conversions [PR #71](https://github.com/shadaj/slinky/pull/71) + **BREAKING**: The tag construction flow now requires attributes to come before children. In addition, an empty list of attributes is no longer allowed [PR #73](https://github.com/shadaj/slinky/pull/73) ++ Add support for all `ReactElement` types introduced in React 16, such as numbers and booleans [PR #83](https://github.com/shadaj/slinky/pull/83) + Add support for error boundaries, which were added in React 16 [PR #82](https://github.com/shadaj/slinky/pull/82) + Add a `*` tag for external components that can take any attribute [PR #81](https://github.com/shadaj/slinky/pull/81) + Fix bugs involving using companion object values from a `@react` annotated component [PR #80](https://github.com/shadaj/slinky/pull/80) diff --git a/core/src/main/scala/me/shadaj/slinky/core/facade/React.scala b/core/src/main/scala/me/shadaj/slinky/core/facade/React.scala index 05415c3b..12b9a84f 100644 --- a/core/src/main/scala/me/shadaj/slinky/core/facade/React.scala +++ b/core/src/main/scala/me/shadaj/slinky/core/facade/React.scala @@ -15,6 +15,22 @@ object ReactElement { s.asInstanceOf[ReactElement] } + @inline implicit def intToElement(i: Int): ReactElement = { + i.asInstanceOf[ReactElement] + } + + @inline implicit def doubleToElement(d: Double): ReactElement = { + d.asInstanceOf[ReactElement] + } + + @inline implicit def floatToElement(f: Float): ReactElement = { + f.asInstanceOf[ReactElement] + } + + @inline implicit def booleanToElement(b: Boolean): ReactElement = { + b.asInstanceOf[ReactElement] + } + @inline implicit def optionToElement(s: Option[ReactElement]): ReactElement = { s.getOrElse(null.asInstanceOf[ReactElement]) } diff --git a/tests/src/test/scala/me/shadaj/slinky/core/ComponentReturnTypeTests.scala b/tests/src/test/scala/me/shadaj/slinky/core/ComponentReturnTypeTests.scala new file mode 100644 index 00000000..a4420689 --- /dev/null +++ b/tests/src/test/scala/me/shadaj/slinky/core/ComponentReturnTypeTests.scala @@ -0,0 +1,50 @@ +package me.shadaj.slinky.core + +import me.shadaj.slinky.core.facade.{Fragment, ReactElement} +import me.shadaj.slinky.web.ReactDOM +import me.shadaj.slinky.web.html._ +import org.scalajs.dom +import org.scalatest.FunSuite + +class ComponentReturnTypeTests extends FunSuite { + def testElement(elem: ReactElement): Unit = { + assert((div(elem): ReactElement) != null) // test use in another element + ReactDOM.render(div(elem), dom.document.createElement("div")) // test rendering to DOM + } + + test("Components can return - arrays") { + testElement(Seq(h1("a"), h1("b"))) + } + + test("Components can return - strings") { + testElement("hello") + } + + test("Components can return - numbers") { + testElement(1) + testElement(1D) + testElement(1F) + } + + test("Components can return - portals") { + testElement(ReactDOM.createPortal(null, dom.document.createElement("div"))) + } + + test("Components can return - null") { + testElement(null) + } + + test("Components can return - booleans") { + testElement(true) + testElement(false) + } + + test("Components can return - options") { + testElement(Some(h1("hi"))) + testElement(None) + } + + test("Components can return - fragments") { + testElement(Fragment(h1("hi"))) + } +}