KotlinPublicationScriptsBui.../web/src/jsMain/kotlin/dev/inmo/kmppscriptbuilder/web/views/ListView.kt

58 lines
2.0 KiB
Kotlin
Raw Normal View History

2021-03-01 20:43:30 +00:00
package dev.inmo.kmppscriptbuilder.web.views
import dev.inmo.micro_utils.common.calculateStrictDiff
2021-03-01 20:43:30 +00:00
import kotlinx.dom.appendElement
import org.w3c.dom.HTMLElement
abstract class ListView<T>(
protected val rootElement: HTMLElement,
useSimpleDiffStrategy: Boolean = false
2021-03-01 20:43:30 +00:00
) : View {
protected val elements = mutableListOf<HTMLElement>()
private val diffHandling: (old: List<T>, new: List<T>) -> Unit = if (useSimpleDiffStrategy) {
{ _, new ->
elements.forEach { it.remove() }
elements.clear()
new.forEach {
val element = instantiateElement()
elements.add(element)
element.placeElement(it)
}
}
} else {
{ old, new ->
val diff = old.calculateStrictDiff(new)
2021-03-01 20:43:30 +00:00
diff.removed.forEach {
elements[it.index].remove()
elements.removeAt(it.index)
println(it.value)
2021-03-01 20:43:30 +00:00
}
diff.added.forEach {
val element = instantiateElement()
elements.add(element)
2021-03-01 20:43:30 +00:00
element.placeElement(it.value)
}
diff.replaced.forEach { (old, new) ->
val element = elements.getOrNull(old.index) ?.also { it.updateElement(old.value, new.value) }
2021-03-01 20:43:30 +00:00
if (element == null) {
val newElement = instantiateElement()
newElement.placeElement(new.value)
elements[new.index] = newElement
2021-03-01 20:43:30 +00:00
}
}
}
}
protected var data: List<T> = emptyList()
set(value) {
val old = field
field = value
diffHandling(old, value)
}
2021-03-01 20:43:30 +00:00
protected abstract fun HTMLElement.placeElement(value: T)
protected abstract fun HTMLElement.updateElement(from: T, to: T)
private fun instantiateElement() = rootElement.appendElement("div") {
classList.add("uk-padding-small")
} as HTMLElement
}