Refactor ObjectTree to functional component

This commit is contained in:
Alexander Nozik 2020-04-18 17:51:26 +03:00
parent ac86832616
commit 28ca287ccd
2 changed files with 51 additions and 54 deletions

View File

@ -1,17 +1,17 @@
package hep.dataforge.js
import react.RComponent
import react.RBuilder
import kotlin.properties.ReadWriteProperty
import kotlin.reflect.KProperty
fun <T> RComponent<*, *>.initState(init: () -> T): ReadWriteProperty<RComponent<*, *>, T> =
object : ReadWriteProperty<RComponent<*, *>, T> {
fun <T> RBuilder.initState(init: () -> T): ReadWriteProperty<Any?, T> =
object : ReadWriteProperty<Any?, T> {
val pair = react.useState(init)
override fun getValue(thisRef: RComponent<*, *>, property: KProperty<*>): T {
override fun getValue(thisRef: Any?, property: KProperty<*>): T {
return pair.first
}
override fun setValue(thisRef: RComponent<*, *>, property: KProperty<*>, value: T) {
override fun setValue(thisRef: Any?, property: KProperty<*>, value: T) {
pair.second(value)
}
}

View File

@ -1,6 +1,7 @@
package hep.dataforge.vis.editor
import hep.dataforge.js.card
import hep.dataforge.js.initState
import hep.dataforge.names.Name
import hep.dataforge.names.plus
import hep.dataforge.names.startsWith
@ -25,20 +26,14 @@ interface TreeState : RState {
var expanded: Boolean
}
class ObjectTree : RComponent<ObjectTreeProps, TreeState>() {
private fun RBuilder.objectTree(props: ObjectTreeProps): Unit {
var expanded: Boolean by initState{ props.selected?.startsWith(props.name) ?: false }
override fun TreeState.init(props: ObjectTreeProps) {
expanded = props.selected?.startsWith(props.name) ?: false
}
private val onClick: (Event) -> Unit = {
setState {
val onClick: (Event) -> Unit = {
expanded = !expanded
}
}
private fun RBuilder.treeLabel(text: String) {
fun RBuilder.treeLabel(text: String) {
button(classes = "btn btn-link tree-label p-0") {
+text
attrs {
@ -50,7 +45,6 @@ class ObjectTree : RComponent<ObjectTreeProps, TreeState>() {
}
}
override fun RBuilder.render() {
val token = props.name.last()?.toString() ?: "World"
val obj = props.obj
@ -60,7 +54,7 @@ class ObjectTree : RComponent<ObjectTreeProps, TreeState>() {
if (obj.children.any { !it.key.body.startsWith("@") }) {
span("tree-caret") {
attrs {
if (state.expanded) {
if (expanded) {
classes += "tree-caret-down"
}
onClickFunction = onClick
@ -69,14 +63,14 @@ class ObjectTree : RComponent<ObjectTreeProps, TreeState>() {
}
treeLabel(token)
}
if (state.expanded) {
if (expanded) {
ul("tree") {
obj.children.entries
.filter { !it.key.toString().startsWith("@") } // ignore statics and other hidden children
.sortedBy { (it.value as? VisualGroup)?.isEmpty ?: true }
.forEach { (childToken, child) ->
li("tree-item") {
child(ObjectTree::class) {
child(ObjectTree) {
attrs {
name = props.name + childToken
this.obj = child
@ -94,15 +88,18 @@ class ObjectTree : RComponent<ObjectTreeProps, TreeState>() {
treeLabel(token)
}
}
}
}
val ObjectTree: FunctionalComponent<ObjectTreeProps> = functionalComponent { props ->
objectTree(props)
}
fun Element.renderObjectTree(
visualObject: VisualObject,
clickCallback: (Name) -> Unit = {}
) = render(this){
) = render(this) {
card("Object tree") {
child(ObjectTree::class) {
child(ObjectTree) {
attrs {
this.name = Name.EMPTY
this.obj = visualObject
@ -117,8 +114,8 @@ fun RBuilder.objectTree(
visualObject: VisualObject,
selected: Name? = null,
clickCallback: (Name) -> Unit = {}
){
child(ObjectTree::class) {
) {
child(ObjectTree) {
attrs {
this.name = Name.EMPTY
this.obj = visualObject