xored / scala-js-react

ScalaJS interface for Facebook React
Apache License 2.0
133 stars 13 forks source link

Children components? #3

Closed dispalt closed 10 years ago

dispalt commented 10 years ago

Is there an example with you using Children components, similar to this (JSX):

/** @jsx React.DOM */

var buttonsInstance = (
    <div>
      <ButtonToolbar>
        <Button bsStyle="primary" bsSize="large">Large button</Button>
        <Button bsSize="large">Large button</Button>
      </ButtonToolbar>
      <ButtonToolbar>
        <Button bsStyle="primary">Default button</Button>
        <Button>Default button</Button>
      </ButtonToolbar>
      <ButtonToolbar>
        <Button bsStyle="primary" bsSize="small">Small button</Button>
        <Button bsSize="small">Small button</Button>
      </ButtonToolbar>
      <ButtonToolbar>
        <Button bsStyle="primary" bsSize="xsmall">Extra small button</Button>
        <Button bsSize="xsmall">Extra small button</Button>
      </ButtonToolbar>
    </div>
  );

React.renderComponent(buttonsInstance, mountNode);

or plain js

/** @jsx React.DOM */

var buttonsInstance = (
    React.DOM.div(null,
      ButtonToolbar(null,
        Button( {bsStyle:"primary", bsSize:"large"}, "Large button"),
        Button( {bsSize:"large"}, "Large button")
      ),
      ButtonToolbar(null,
        Button( {bsStyle:"primary"}, "Default button"),
        Button(null, "Default button")
      ),
      ButtonToolbar(null,
        Button( {bsStyle:"primary", bsSize:"small"}, "Small button"),
        Button( {bsSize:"small"}, "Small button")
      ),
      ButtonToolbar(null,
        Button( {bsStyle:"primary", bsSize:"xsmall"}, "Extra small button"),
        Button( {bsSize:"xsmall"}, "Extra small button")
      )
    )
  );

React.renderComponent(buttonsInstance, mountNode);

I haven't gotten it to work. It looks like you assume everything passed in after the first component is a ref. Any insight how to wire this up?

kanterov commented 10 years ago

I wasn't aware that it's possible to createComponent without doing createClass. I would work on this.

As I know, In react children is just syntax sugar for specifying children property, so your example could be written with components:

import org.scalajs.react._

object Button extends TypedReactSpec {
  case class State()
  case class Props(style: Option[String] = None, size: String, label: String)

  def getInitialState(self: This) = State()

  @scalax
  def render(self: This) = {
    <button>{self.props.label}</button>
  }
}

object ButtonToolbar extends TypedReactSpec {
  case class State()

  // possible to constraint type with `Button.ComponentType`
  case class Props(children: ReactDOM*)

  def getInitialState(self: This) = State()

  @scalax
  def render(self: This) = {
    <div className="button-toolbar">
      {
        for {
          button <- self.props.children
        } yield button
      }
    </div>
  }
}

object Buttons extends TypedReactSpec {
  case class State()
  case class Props()

  def getInitialState(self: This) = State()

  @scalax
  def render(self: This) = {
    <div>
      {
        ButtonToolbar(ButtonToolbar.Props(
          Button(Button.Props(style = Some("primary"), size = "small", label = "Small button")),
          Button(Button.Props(size = "small", label = "Small button"))
        ))
      }
      {
        ButtonToolbar(ButtonToolbar.Props(
          Button(Button.Props(style = Some("primary"), size = "xsmall", label = "Extra Small button")),
          Button(Button.Props(size = "xsmall", label = "Extra Small button"))
        ))
      }
    </div>
  }
}
kanterov commented 10 years ago

I've just fixed ReactDOM rendering and pushed an example involving features that you have mentioned. Please confirm that we are on the same page :).

kanterov commented 10 years ago

Hey @ddispaltro

dispalt commented 10 years ago

Sorry for the delay. Yeah this what I was looking for, thanks!