Skip to content

Instantly share code, notes, and snippets.

@jamowei

jamowei/app.kt Secret

Last active January 19, 2021 21:25
Show Gist options
  • Save jamowei/d485f7a1c588ffa38929979d6bade5e4 to your computer and use it in GitHub Desktop.
Save jamowei/d485f7a1c588ffa38929979d6bade5e4 to your computer and use it in GitHub Desktop.
Components Validation
fun main() {
val store = object : RootStore<Car>(
Car("car", Color(120, 120, 120)),
id = "car"
), WithValidator<Car, Unit> {
override val validator = CarValidator
init { validate(Unit) }
}
val intFormat = format({ it.toInt() }, { it.toString() })
val nameStore = store.sub(L.Car.name)
val colorStore = store.sub(L.Car.color)
val redStore = colorStore.sub(L.Color.r).sub(intFormat)
val greenStore = colorStore.sub(L.Color.g).sub(intFormat)
val blueStore = colorStore.sub(L.Color.b).sub(intFormat)
fun RenderContext.validatedInput(store: Store<String>, label: String) {
div {
label { +label }
val msg = store.validationMessage().map { it?.message ?: "" }
input(id = store.id) {
value(store.data)
changes.values() handledBy store.update
}
span {
inlineStyle("color: red")
msg.asText()
}
}
}
render {
h3 {
store.data.map { it.toString() }.asText()
}
div {
p { +"Validation Messages" }
ul {
store.validator.filter { it.isError() }.renderEach {
li { +it.message }
}
}
}
div {
validatedInput(nameStore, "Car name")
validatedInput(redStore, "Red color")
validatedInput(greenStore, "Green color")
validatedInput(blueStore, "Blue color")
}
div {
hr {}
button {
+"Multiple Validation Messages"
clicks.map { Car("", Color(-1, 256, -1)) } handledBy store.update
}
p { +"Color Warnings" }
ul {
store.validationMessages().renderEach {
li { +it.message }
}
}
}
}
}
@Lenses
data class Car(val name: String, val color: Color)
@Lenses
data class Color(val r: Int, val g: Int, val b: Int)
object CarValidator : ComponentValidator<Car, Unit>() {
override fun validate(data: Car, metadata: Unit): List<ComponentValidationMessage> {
val msgs = mutableListOf<ComponentValidationMessage>()
val inspector = inspect(data)
val name = inspector.sub(L.Car.name)
if (name.data.isBlank()) {
msgs.add(errorMessage(name.id, "car name can not be blank"))
msgs.add(warningMessage("car", "car name can not be blank"))
}
val color = inspector.sub(L.Car.color)
fun checkColorBound(color: SubInspector<Car, Color, Int>, name: String) {
if(color.data > 255) {
msgs.add(errorMessage(color.id, "$name color value is to high"))
msgs.add(warningMessage("car", "$name color value is to high"))
}
if(color.data < 0) {
msgs.add(errorMessage(color.id, "$name color value is to low"))
msgs.add(warningMessage("car", "$name color value is to low"))
}
}
checkColorBound(color.sub(L.Color.r), "red")
checkColorBound(color.sub(L.Color.g), "green")
checkColorBound(color.sub(L.Color.b), "blue")
return msgs
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment