Created
May 14, 2014 05:43
-
-
Save benjaminjackman/063673e3bf6d885cc083 to your computer and use it in GitHub Desktop.
ScalaJS Idealized Type Wrappers for React Experimentation
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package cgta.viz.learn.react | |
import scala.scalajs.js.annotation.JSExport | |
import scala.scalajs.js | |
import org.scalajs.dom.HTMLElement | |
@JSExport | |
object ReactTodo { | |
//Some helpers I use. | |
import BenSjs._ | |
//Proposed annotation for typing a function that has a js.This | |
//Maybe a bad idea? | |
class JSThis[T] extends scala.annotation.StaticAnnotation | |
//Work in progress React wrappers | |
object React extends js.Object { | |
def createClass(init: ReactClassInit): ReactClassBuilder = ??? | |
def renderComponent(cls: ReactClassInstance, mountNode: HTMLElement) = ??? | |
object DOM { | |
def div(huh: js.Any, something: js.String, propsOrWhat: js.Any) = ??? | |
} | |
} | |
trait ReactClassInstance extends js.Object | |
trait ReactClassBuilder { | |
def apply(args: js.Object): ReactClassInstance | |
} | |
trait ReactClassInit extends js.Object { | |
@JSThis[js.Dynamic] | |
def render() : js.Any | |
} | |
@JSExport | |
def main() { | |
helloJonT() | |
} | |
//Ideal Typed Example | |
def helloJonT() { | |
val HelloMessage = React.createClass(new ReactClassInit { | |
//Does the annotation need to be re stated each time? | |
@JSThis[js.Dynamic] | |
override def render() = { | |
//js.this only legal in functions that have the jsThis annotation | |
//How does this work for anonymous functions? Use the current syntax for them? | |
React.DOM.div(null, "Hello ", js.this.props.name) | |
} | |
}) | |
React.renderComponent(HelloMessage(*(name = "Jon").asInstanceOf[js.Object]), document.getElementById("content")) | |
} | |
//Type Dynamic example: | |
def helloJon() { | |
val React = global.React | |
val HelloMessage = React.createClass(*( | |
render = new js.ThisFunction0[js.Dynamic, js.Any] { | |
override def apply(thisArg: js.Dynamic): js.Any = { | |
React.DOM.div(null, "Hello ", thisArg.props.name) | |
} | |
} | |
)) | |
React.renderComponent(HelloMessage(*(name = "Jon")), document.getElementById("content")) | |
} | |
} | |
object BenSjs { | |
trait JsConsole extends js.Object { | |
def debug(xs: js.Any*) | |
def log(xs: js.Any*) | |
def warn(xs: js.Any*) | |
def error(xs: js.Any*) | |
} | |
val global = js.Dynamic.global | |
val console = global.console.asInstanceOf[JsConsole] | |
val JSON = global.JSON | |
val undefined = global.undefined | |
val window = global.window | |
val document = org.scalajs.dom.document | |
// def newObject = js.Object().asInstanceOf[js.Dynamic] | |
def new_*(clazz: js.Dynamic)(args: js.Any*): js.Dynamic = js.Dynamic.newInstance(clazz)(args: _*) | |
val * = js.Dynamic.literal | |
type * = js.Dynamic | |
def log(args: js.Any*) = console.log(args: _*) | |
//Use for for loops when porting over javascript code, not quite the same, but easier than converting to a while loop | |
def jfor[A](init: A, p: A => Boolean, inc: A => A)(f: A => Unit) { | |
var x = init | |
while (p(x)) { | |
f(x) | |
x = inc(x) | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment