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)
* [komponent](https://github.com/rnentjes/komponent)
Complete source:
This is the complete source:
```kotlin
package nl.astraeus.komp.todo
import kotlinx.html.HtmlBlockTag
import kotlinx.html.InputType
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.browser.document
import kotlinx.html.*
import kotlinx.html.js.onClickFunction
import kotlinx.html.js.onDoubleClickFunction
import kotlinx.html.js.onKeyPressFunction
import kotlinx.html.label
import kotlinx.html.li
import kotlinx.html.section
import kotlinx.html.span
import kotlinx.html.strong
import kotlinx.html.ul
import nl.astraeus.komp.HtmlBuilder
import nl.astraeus.komp.Komponent
import nl.astraeus.komp.include
import org.w3c.dom.HTMLElement
import org.w3c.dom.HTMLInputElement
import org.w3c.dom.events.Event
import org.w3c.dom.events.KeyboardEvent
import kotlin.browser.document
import kotlin.js.Date
/**
@@ -51,10 +33,10 @@ import kotlin.js.Date
*/
class Todo(
val dataId: String,
var title: String,
var completed: Boolean = false,
var editing: Boolean = false
val dataId: String,
var title: String,
var completed: Boolean = false,
var editing: Boolean = false
)
enum class Selection(val title: String) {
@@ -63,50 +45,48 @@ enum class Selection(val title: String) {
COMPLETED("Completed")
}
fun HtmlBlockTag.todo(app: TodoApp, todo: Todo) {
this.include(TodoKomponent(app, todo))
}
class TodoKomponent(
val app: TodoApp,
val todo: Todo
val app: TodoApp,
val todo: Todo
) : Komponent() {
override fun render(consumer: TagConsumer<HTMLElement>) = consumer.li {
if (todo.editing) {
classes += "editing"
input(classes = "edit") {
value = todo.title
onKeyPressFunction = { e ->
val target = e.target
if (target is HTMLInputElement && e is KeyboardEvent && e.keyCode == 13 && target.value.isNotBlank()) {
app.editTodo(e, todo)
override fun HtmlBuilder.render() {
li {
if (todo.editing) {
classes = classes + "editing"
input(classes = "edit") {
value = todo.title
onKeyPressFunction = { e ->
val target = e.target
if (target is HTMLInputElement && e is KeyboardEvent && e.keyCode == 13 && target.value.isNotBlank()) {
app.editTodo(e, todo)
}
}
}
}
} else {
if (todo.completed) {
classes += "completed"
}
attributes["data-id"] = todo.dataId
div(classes = "view") {
input(classes = "toggle") {
type = InputType.checkBox
checked = todo.completed
onClickFunction = {
app.todoClicked(todo)
}
} else {
if (todo.completed) {
classes = classes + "completed"
}
label(classes = "todo-content") {
+todo.title
div(classes = "view") {
input(classes = "toggle") {
type = InputType.checkBox
checked = todo.completed
onClickFunction = {
app.todoClicked(todo)
it.preventDefault()
}
}
label(classes = "todo-content") {
+todo.title
onDoubleClickFunction = {
app.setEditing(todo)
onDoubleClickFunction = {
app.setEditing(todo)
}
}
}
button(classes = "destroy") {
onClickFunction = {
app.destroyTodo(todo)
button(classes = "destroy") {
onClickFunction = {
app.destroyTodo(todo)
}
}
}
}
@@ -125,7 +105,7 @@ class TodoApp : Komponent() {
if (target is HTMLInputElement) {
todoList.add(Todo("${Date().getTime()}", target.value))
refresh()
requestUpdate()
}
}
@@ -136,7 +116,7 @@ class TodoApp : Komponent() {
todo.title = target.value
todo.editing = false
refresh()
requestUpdate()
}
}
@@ -144,13 +124,13 @@ class TodoApp : Komponent() {
fun destroyTodo(todo: Todo) {
todoList.remove(todo)
refresh()
requestUpdate()
}
fun selectSelection(selection: Selection) {
selected = selection
refresh()
requestUpdate()
}
fun clearCompleted() {
@@ -160,13 +140,13 @@ class TodoApp : Komponent() {
}
}
refresh()
requestUpdate()
}
fun todoClicked(todo: Todo) {
todo.completed = !todo.completed
refresh()
requestUpdate()
}
fun getItemsLeft(): Int {
@@ -184,82 +164,81 @@ class TodoApp : Komponent() {
todo.editing = todo == editTodo
}
refresh()
requestUpdate()
}
override fun refresh() {
super.refresh()
override fun HtmlBuilder.render() {
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) {
inputBox.focus()
}
}
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)
}
target.value = ""
target.defaultValue = ""
}
}
}
}
button(classes = "clear-completed") {
+"Clear completed"
onClickFunction = {
clearCompleted()
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)) {
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() {
Komponent.create(document.body!!, TodoApp(), true)
Komponent.create(document.body!!, TodoApp())
}
```

View File

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