Cleanup, update readme

This commit is contained in:
2022-01-15 14:27:35 +01:00
parent 160db39005
commit 608d3d9853
2 changed files with 116 additions and 142 deletions

253
readme.md
View File

@@ -11,39 +11,21 @@ Dependencies:
* [kotlinx-html-js](https://github.com/Kotlin/kotlinx.html) * [kotlinx-html-js](https://github.com/Kotlin/kotlinx.html)
* [komponent](https://github.com/rnentjes/komponent) * [komponent](https://github.com/rnentjes/komponent)
Complete source: This is the complete source:
```kotlin ```kotlin
package nl.astraeus.komp.todo package nl.astraeus.komp.todo
import kotlinx.html.HtmlBlockTag import kotlinx.browser.document
import kotlinx.html.InputType import kotlinx.html.*
import kotlinx.html.TagConsumer
import kotlinx.html.a
import kotlinx.html.button
import kotlinx.html.classes
import kotlinx.html.div
import kotlinx.html.footer
import kotlinx.html.h1
import kotlinx.html.header
import kotlinx.html.id
import kotlinx.html.input
import kotlinx.html.js.onClickFunction import kotlinx.html.js.onClickFunction
import kotlinx.html.js.onDoubleClickFunction import kotlinx.html.js.onDoubleClickFunction
import kotlinx.html.js.onKeyPressFunction import kotlinx.html.js.onKeyPressFunction
import kotlinx.html.label import nl.astraeus.komp.HtmlBuilder
import kotlinx.html.li
import kotlinx.html.section
import kotlinx.html.span
import kotlinx.html.strong
import kotlinx.html.ul
import nl.astraeus.komp.Komponent import nl.astraeus.komp.Komponent
import nl.astraeus.komp.include
import org.w3c.dom.HTMLElement
import org.w3c.dom.HTMLInputElement import org.w3c.dom.HTMLInputElement
import org.w3c.dom.events.Event import org.w3c.dom.events.Event
import org.w3c.dom.events.KeyboardEvent import org.w3c.dom.events.KeyboardEvent
import kotlin.browser.document
import kotlin.js.Date import kotlin.js.Date
/** /**
@@ -51,10 +33,10 @@ import kotlin.js.Date
*/ */
class Todo( class Todo(
val dataId: String, val dataId: String,
var title: String, var title: String,
var completed: Boolean = false, var completed: Boolean = false,
var editing: Boolean = false var editing: Boolean = false
) )
enum class Selection(val title: String) { enum class Selection(val title: String) {
@@ -63,50 +45,48 @@ enum class Selection(val title: String) {
COMPLETED("Completed") COMPLETED("Completed")
} }
fun HtmlBlockTag.todo(app: TodoApp, todo: Todo) {
this.include(TodoKomponent(app, todo))
}
class TodoKomponent( class TodoKomponent(
val app: TodoApp, val app: TodoApp,
val todo: Todo val todo: Todo
) : Komponent() { ) : Komponent() {
override fun render(consumer: TagConsumer<HTMLElement>) = consumer.li { override fun HtmlBuilder.render() {
if (todo.editing) { li {
classes += "editing" if (todo.editing) {
input(classes = "edit") { classes = classes + "editing"
value = todo.title input(classes = "edit") {
onKeyPressFunction = { e -> value = todo.title
val target = e.target onKeyPressFunction = { e ->
if (target is HTMLInputElement && e is KeyboardEvent && e.keyCode == 13 && target.value.isNotBlank()) { val target = e.target
app.editTodo(e, todo) if (target is HTMLInputElement && e is KeyboardEvent && e.keyCode == 13 && target.value.isNotBlank()) {
app.editTodo(e, todo)
}
} }
} }
} } else {
} else { if (todo.completed) {
if (todo.completed) { classes = classes + "completed"
classes += "completed"
}
attributes["data-id"] = todo.dataId
div(classes = "view") {
input(classes = "toggle") {
type = InputType.checkBox
checked = todo.completed
onClickFunction = {
app.todoClicked(todo)
}
} }
label(classes = "todo-content") { div(classes = "view") {
+todo.title input(classes = "toggle") {
type = InputType.checkBox
checked = todo.completed
onClickFunction = {
app.todoClicked(todo)
it.preventDefault()
}
}
label(classes = "todo-content") {
+todo.title
onDoubleClickFunction = { onDoubleClickFunction = {
app.setEditing(todo) app.setEditing(todo)
}
} }
} button(classes = "destroy") {
button(classes = "destroy") { onClickFunction = {
onClickFunction = { app.destroyTodo(todo)
app.destroyTodo(todo) }
} }
} }
} }
@@ -125,7 +105,7 @@ class TodoApp : Komponent() {
if (target is HTMLInputElement) { if (target is HTMLInputElement) {
todoList.add(Todo("${Date().getTime()}", target.value)) todoList.add(Todo("${Date().getTime()}", target.value))
refresh() requestUpdate()
} }
} }
@@ -136,7 +116,7 @@ class TodoApp : Komponent() {
todo.title = target.value todo.title = target.value
todo.editing = false todo.editing = false
refresh() requestUpdate()
} }
} }
@@ -144,13 +124,13 @@ class TodoApp : Komponent() {
fun destroyTodo(todo: Todo) { fun destroyTodo(todo: Todo) {
todoList.remove(todo) todoList.remove(todo)
refresh() requestUpdate()
} }
fun selectSelection(selection: Selection) { fun selectSelection(selection: Selection) {
selected = selection selected = selection
refresh() requestUpdate()
} }
fun clearCompleted() { fun clearCompleted() {
@@ -160,13 +140,13 @@ class TodoApp : Komponent() {
} }
} }
refresh() requestUpdate()
} }
fun todoClicked(todo: Todo) { fun todoClicked(todo: Todo) {
todo.completed = !todo.completed todo.completed = !todo.completed
refresh() requestUpdate()
} }
fun getItemsLeft(): Int { fun getItemsLeft(): Int {
@@ -184,82 +164,81 @@ class TodoApp : Komponent() {
todo.editing = todo == editTodo todo.editing = todo == editTodo
} }
refresh() requestUpdate()
} }
override fun refresh() { override fun HtmlBuilder.render() {
super.refresh() section(classes = "todoapp") {
header(classes = "header") {
h1 { +"todos" }
input(classes = "new-todo") {
id = "todo_input"
placeholder = "What needs to be done?"
autoFocus = true
onKeyPressFunction = { e ->
val target = e.target
if (target is HTMLInputElement &&
e is KeyboardEvent &&
e.keyCode == 13 &&
target.value.isNotBlank()
) {
e.preventDefault()
e.stopPropagation()
val inputBox = document.getElementById("todo_input") addTodo(e)
if (inputBox is HTMLInputElement) { target.value = ""
inputBox.focus() target.defaultValue = ""
}
}
override fun render(consumer: TagConsumer<HTMLElement>) = consumer.section(classes = "todoapp") {
header(classes = "header") {
h1 { +"todos" }
input(classes = "new-todo") {
id = "todo_input"
placeholder = "What needs to be done?"
autoFocus = true
onKeyPressFunction = { e ->
val target = e.target
if (target is HTMLInputElement && e is KeyboardEvent && e.keyCode == 13 && target.value.isNotBlank()) {
addTodo(e)
target.value = ""
target.defaultValue = ""
}
}
}
}
section(classes = "main") {
input(classes = "toggle-all") {
type = InputType.checkBox
}
label {
htmlFor = "toggle-all"
+"Mark all as complete"
}
ul(classes = "todo-list") {
for (todo in todoList) {
if (selected == Selection.ALL ||
(todo.completed && selected == Selection.COMPLETED) ||
(!todo.completed && selected == Selection.ACTIVE)) {
todo(this@TodoApp, todo)
}
}
}
}
footer(classes = "footer") {
span(classes = "todo-count") {
strong { +"${getItemsLeft()}" }
+" item left"
}
ul(classes = "filters") {
for (selection in Selection.values()) {
li {
a {
if (selection == selected) {
classes += "selected"
}
href = "#"
+selection.title
onClickFunction = {
selectSelection(selection)
}
} }
} }
} }
} }
button(classes = "clear-completed") {
+"Clear completed" section(classes = "main") {
onClickFunction = { input(classes = "toggle-all") {
clearCompleted() type = InputType.checkBox
}
label {
htmlFor = "toggle-all"
+ "Mark all as complete"
}
ul(classes = "todo-list") {
for (todo in todoList) {
if (selected == Selection.ALL ||
(todo.completed && selected == Selection.COMPLETED) ||
(!todo.completed && selected == Selection.ACTIVE)) {
include(TodoKomponent(this@TodoApp, todo))
}
}
}
}
footer(classes = "footer") {
span(classes = "todo-count") {
strong { +"${getItemsLeft()}" }
+" item left"
}
ul(classes = "filters") {
for (selection in Selection.values()) {
li {
a {
if (selection == selected) {
classes = classes + "selected"
}
href = "#"
+selection.title
onClickFunction = {
selectSelection(selection)
}
}
}
}
}
button(classes = "clear-completed") {
+"Clear completed"
onClickFunction = {
clearCompleted()
}
} }
} }
} }
@@ -268,6 +247,6 @@ class TodoApp : Komponent() {
} }
fun main() { fun main() {
Komponent.create(document.body!!, TodoApp(), true) Komponent.create(document.body!!, TodoApp())
} }
``` ```

View File

@@ -231,10 +231,5 @@ class TodoApp : Komponent() {
} }
fun main() { fun main() {
Komponent.logReplaceEvent = false
Komponent.logRenderEvent = false
println("Create TodoApp()")
Komponent.create(document.body!!, TodoApp()) Komponent.create(document.body!!, TodoApp())
} }