Skip to content

Instantly share code, notes, and snippets.

@rleibman
Created June 26, 2020 19:05
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rleibman/b3444d3fd7f17fa8763adf1204a9fbfa to your computer and use it in GitHub Desktop.
Save rleibman/b3444d3fd7f17fa8763adf1204a9fbfa to your computer and use it in GitHub Desktop.
object ParentComponent {
val ctx: Context[ParentState] = React.createContext(ParentState())
case class ChildProps(childName: String, addMenuProvider: (() => Seq[(String, Callback)]) => Callback)
case class ChildState(childName: String, childString: String = "Child String", strings: Seq[String] = Seq.empty)
class ChildBackend($ : BackendScope[ChildProps, ChildState]) {
def childMenuProvider(s: ChildState)(): Seq[(String, Callback)] = {
val items = Seq(
(
"MenuItem1",
Callback
.log("Hit MenuItem1") >> $.modState(s => s.copy(strings = s.strings :+ "1")) >> Callback(
println("Hello World1")
)
),
(
"MenuItem2",
Callback
.log("Hit MenuItem2") >> $.modState(s => s.copy(strings = s.strings :+ "2")) >> Callback(
println("Hello World2")
)
),
(
s.childString,
Callback
.log("Hit childString") >> $.modState(s => s.copy(strings = s.strings :+ s.childString)) >> Callback(
println("childString")
)
),
)
if(s.childName == "child1") items.drop(1) else items
}
def render(s: ChildState): VdomElement = {
ctx.consume { useThisState =>
<.div(<.h1("Stuff"), <.h2(useThisState.someString), s.strings.toVdomArray(str => <.div(str)))
}
}
}
private val childComponent = ScalaComponent
.builder[ChildProps]("child")
.initialStateFromProps(p => ChildState(p.childName))
.renderBackend[ChildBackend]
.componentDidMount($ => $.props.addMenuProvider($.backend.childMenuProvider($.state)))
.build
def ChildComponent(props: ChildProps): Unmounted[ChildProps, ChildState, ChildBackend] = childComponent(props)
case class ParentState(someString: String = "This is just a string", menuProviders: Seq[() => Seq[(String, Callback)]] = Seq.empty)
class ParentBackend($ : BackendScope[Unit, ParentState]) {
def addMenuProvider(menuProvider: () => Seq[(String, Callback)]): Callback = {
$.modState(s => s.copy(menuProviders = s.menuProviders :+ menuProvider))
}
def render(state: ParentState): VdomElement = {
ctx.provide(state) {
ctx.consume { useThisState =>
<.div(
useThisState.menuProviders
.flatMap(_ ()).toVdomArray(i =>
<.div(<.button(^.onClick ==> { a =>
i._2
}, i._1))
),
<.br(),
ChildComponent(ChildProps("child1", addMenuProvider)),
ChildComponent(ChildProps("child2", addMenuProvider))
)
}
}
}
}
private val parentComponent = ScalaComponent
.builder[Unit]("parent")
.initialState(ParentState())
.renderBackend[ParentBackend]
.build
def apply(): Unmounted[Unit, ParentState, ParentBackend] = parentComponent()
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment