DConfig/src/main/kotlin/components/JsonObject.kt

126 lines
3.7 KiB
Kotlin

package components
import ValueChangeEvent
import kotlinx.css.*
import kotlinx.html.classes
import kotlinx.html.js.onClickFunction
import kotlinx.serialization.json.buildJsonObject
import react.*
import react.dom.attrs
import schema.ConfigSchema
import styled.*
external interface JsonObjectProps: Props {
var schema: ConfigSchema
var name: String
var data: kotlinx.serialization.json.JsonObject?
var id: String
var handleChange: (event: ValueChangeEvent) -> Unit
var level: Int
}
data class JsonObjectState(
var data: kotlinx.serialization.json.JsonObject?,
var showChildren: Boolean = true,
): State
class JsonObject(props: JsonObjectProps): RComponent<JsonObjectProps, JsonObjectState>() {
init {
this.state = JsonObjectState(
data = props.data,
)
}
override fun RBuilder.render() {
styledDiv {
css {
if (props.name != "") {
borderColor = hsl((props.level * 40) % 256, 100, 15)
+Styles.objectContainer
}
}
if (props.name != "") {
styledDiv {
css {
+Styles.objectHeader
}
styledI {
attrs {
classes = if (state.showChildren) {
setOf("ri-arrow-down-s-line", "ri-xl")
} else {
setOf("ri-arrow-right-s-line", "ri-xl")
}
onClickFunction = {
setState {
showChildren = !showChildren
}
}
}
}
styledLabel {
css {
textTransform = TextTransform.capitalize
}
+props.name
}
styledDiv {
css {
width = 24.px
}
}
}
}
styledDiv {
css {
if (!state.showChildren)
display = Display.none
}
descriptionBlock(props.schema.description)
for (property in props.schema.children!!) {
jsonSchema(
schema = property.value,
name = property.key,
data = state.data?.get(property.key),
id = property.key,
handleChange = ::handleChange,
level = props.level + 1,
)
}
}
}
}
fun handleChange(event: ValueChangeEvent) {
state.data = buildJsonObject {
if (state.data != null)
for (entry in state.data!!) {
put(entry.key, entry.value)
}
put(event.id, event.value)
}
props.handleChange(ValueChangeEvent(props.id, state.data!!))
}
}
fun RBuilder.jsonObject(schema: ConfigSchema, name: String, data: kotlinx.serialization.json.JsonObject?, id: String, handleChange: (event: ValueChangeEvent) -> Unit, level: Int) {
child(JsonObject::class) {
attrs {
this.schema = schema
this.name = name
this.data = data
this.id = id
this.handleChange = handleChange
this.level = level
}
}
}