diff options
Diffstat (limited to 'examples/scalajs-react-example/js')
-rw-r--r-- | examples/scalajs-react-example/js/App.scala | 15 | ||||
-rw-r--r-- | examples/scalajs-react-example/js/Pictures.scala | 102 | ||||
-rw-r--r-- | examples/scalajs-react-example/js/build/build.scala | 22 | ||||
-rw-r--r-- | examples/scalajs-react-example/js/build/build/build.scala | 4 |
4 files changed, 143 insertions, 0 deletions
diff --git a/examples/scalajs-react-example/js/App.scala b/examples/scalajs-react-example/js/App.scala new file mode 100644 index 0000000..0cd170e --- /dev/null +++ b/examples/scalajs-react-example/js/App.scala @@ -0,0 +1,15 @@ +package prototype + +import japgolly.scalajs.react.ReactDOM +import org.scalajs.dom + +import scala.scalajs.js.JSApp +import scala.scalajs.js.annotation.JSExport + +@JSExport("App") +object App extends JSApp { + def main(): Unit = { + val doc = dom.document + ReactDOM.render(Pictures.PictureComponent(), doc.getElementById("main")) + } +} diff --git a/examples/scalajs-react-example/js/Pictures.scala b/examples/scalajs-react-example/js/Pictures.scala new file mode 100644 index 0000000..db1d7ef --- /dev/null +++ b/examples/scalajs-react-example/js/Pictures.scala @@ -0,0 +1,102 @@ +package prototype + +import japgolly.scalajs.react.{ReactComponentB, BackendScope, Callback} +import org.scalajs.dom + +import scala.scalajs._ +import japgolly.scalajs.react.vdom.all._ + +import scala.scalajs.js.JSON + +object Pictures { + + case class State(pictures: List[Picture], favourites: List[Picture]) + + type PicClick = (String, Boolean) => Callback + + class Backend($: BackendScope[Unit, State]) { + + def onPicClick(id: String, favorite: Boolean) = + $.state flatMap { s => + if (favorite) { + val newPics = s.pictures.map(p => if (p.id == id) p.copy(favorite = false) else p) + val newFavs = s.favourites.filter(p => p.id != id) + $.modState(_ => State(newPics, newFavs)) + } else { + var newPic: Picture = null + val newPics = s.pictures.map(p => if (p.id == id) { + newPic = p.copy(favorite = true); newPic + } else p) + val newFavs = s.favourites.+:(newPic) + $.modState(_ => State(newPics, newFavs)) + } + } + + def render(s: State) = + div( + h1("Popular Pixabay Pics"), + pictureList((s.pictures, onPicClick)), + h1("Your favorites"), + favoriteList((s.favourites, onPicClick))) + } + + val picture = ReactComponentB[(Picture, PicClick)]("picture") + .render_P { case (p, b) => + div(if (p.favorite) cls := "picture favorite" else cls := "picture", onClick --> b(p.id, p.favorite))( + img(src := p.src, title := p.title) + ) + } + .build + + val pictureList = ReactComponentB[(List[Picture], PicClick)]("pictureList") + .render_P { case (list, b) => + div(`class` := "pictures")( + if (list.isEmpty) span("Loading Pics..") + else { + list.map(p => picture.withKey(p.id)((p, b))) + } + ) + } + .build + + val favoriteList = ReactComponentB[(List[Picture], PicClick)]("favoriteList") + .render_P { case (list, b) => + div(`class` := "favorites")( + if (list.isEmpty) span("Click an image to mark as favorite") + else { + list.map(p => picture.withKey(p.id)((p, b))) + } + ) + } + .build + + val PictureComponent = ReactComponentB[Unit]("PictureComponent") + .initialState(State(Nil, Nil)) + .renderBackend[Backend] + .componentDidMount(scope => Callback { + import scalajs.js.Dynamic.{global => g} + def isDefined(g: js.Dynamic): Boolean = + g.asInstanceOf[js.UndefOr[AnyRef]].isDefined + val url = "http://localhost:3000/data" + val xhr = new dom.XMLHttpRequest() + xhr.open("GET", url) + xhr.onload = { (e: dom.Event) => + if (xhr.status == 200) { + val result = JSON.parse(xhr.responseText) + if (isDefined(result) && isDefined(result.hits)) { + val hits = result.hits.asInstanceOf[js.Array[js.Dynamic]] + val pics = hits.toList.map(item => Picture( + item.id.toString, + item.pageURL.toString, + item.previewURL.toString, + if (item.tags != null) item.tags.asInstanceOf[js.Array[String]].mkString(",") else "")) + //if (item.caption != null) item.caption.text.toString else "")) + scope.modState(_ => State(pics, Nil)).runNow() + } + } + } + xhr.send() + }) + .buildU + +} diff --git a/examples/scalajs-react-example/js/build/build.scala b/examples/scalajs-react-example/js/build/build.scala new file mode 100644 index 0000000..29f1c73 --- /dev/null +++ b/examples/scalajs-react-example/js/build/build.scala @@ -0,0 +1,22 @@ +import cbt._ +class Build(val context: Context) extends ScalaJsBuild{ + override val projectName = "my-project" + + override def sources = super.sources ++ Seq( + projectDirectory.getParentFile ++ "/shared" + ) + + override def dependencies = ( + super.dependencies ++ + Resolver( mavenCentral ).bind( + //"org.scalatest" %%% "scalatest" % "3.0.0-RC2", + "com.github.japgolly.scalajs-react" %%% "core" % "0.10.4", // for example + // for example if you want explicitely state scala version + "org.scala-js" % "scalajs-dom_sjs0.6_2.11" % "0.9.0" + ) + ) + + override protected def fastOptJSFile = { + projectDirectory.getParentFile ++ "/server/public" ++ ("/"++super.fastOptJSFile.getName) + } +} diff --git a/examples/scalajs-react-example/js/build/build/build.scala b/examples/scalajs-react-example/js/build/build/build.scala new file mode 100644 index 0000000..b30e005 --- /dev/null +++ b/examples/scalajs-react-example/js/build/build/build.scala @@ -0,0 +1,4 @@ +import cbt._ +class Build(val context: Context) extends BuildBuild{ + override def dependencies = super.dependencies :+ plugins.scalaJs +} |