Update kotlin version, use MPP, update komp version
This commit is contained in:
6
.idea/artifacts/komp_todo_jslegacy_0_1_0_SNAPSHOT.xml
generated
Normal file
6
.idea/artifacts/komp_todo_jslegacy_0_1_0_SNAPSHOT.xml
generated
Normal file
@@ -0,0 +1,6 @@
|
||||
<component name="ArtifactManager">
|
||||
<artifact type="jar" name="komp-todo-jslegacy-0.1.0-SNAPSHOT">
|
||||
<output-path>$PROJECT_DIR$/build/libs</output-path>
|
||||
<root id="archive" name="komp-todo-jslegacy-0.1.0-SNAPSHOT.jar" />
|
||||
</artifact>
|
||||
</component>
|
||||
6
.idea/compiler.xml
generated
Normal file
6
.idea/compiler.xml
generated
Normal file
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="CompilerConfiguration">
|
||||
<bytecodeTargetLevel target="1.8" />
|
||||
</component>
|
||||
</project>
|
||||
7
.idea/gradle.xml
generated
7
.idea/gradle.xml
generated
@@ -4,15 +4,16 @@
|
||||
<component name="GradleSettings">
|
||||
<option name="linkedExternalProjectsSettings">
|
||||
<GradleProjectSettings>
|
||||
<option name="distributionType" value="DEFAULT_WRAPPED" />
|
||||
<option name="delegatedBuild" value="true" />
|
||||
<option name="testRunner" value="GRADLE" />
|
||||
<option name="distributionType" value="WRAPPED" />
|
||||
<option name="externalProjectPath" value="$PROJECT_DIR$" />
|
||||
<option name="gradleJvm" value="1.8" />
|
||||
<option name="modules">
|
||||
<set>
|
||||
<option value="$PROJECT_DIR$" />
|
||||
</set>
|
||||
</option>
|
||||
<option name="resolveModulePerSourceSet" value="false" />
|
||||
<option name="useAutoImport" value="true" />
|
||||
</GradleProjectSettings>
|
||||
</option>
|
||||
</component>
|
||||
|
||||
6
.idea/hotswap_agent.xml
generated
6
.idea/hotswap_agent.xml
generated
@@ -1,6 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="HotSwapAgentPluginSettingsProvider">
|
||||
<option name="agentPath" value="$APPLICATION_PLUGINS_DIR$/hotswap-agent-intellij-plugin/lib/agent/hotswap-agent-1.3.0.jar" />
|
||||
</component>
|
||||
</project>
|
||||
35
.idea/jarRepositories.xml
generated
Normal file
35
.idea/jarRepositories.xml
generated
Normal file
@@ -0,0 +1,35 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="RemoteRepositoriesConfiguration">
|
||||
<remote-repository>
|
||||
<option name="id" value="central" />
|
||||
<option name="name" value="Maven Central repository" />
|
||||
<option name="url" value="https://repo1.maven.org/maven2" />
|
||||
</remote-repository>
|
||||
<remote-repository>
|
||||
<option name="id" value="jboss.community" />
|
||||
<option name="name" value="JBoss Community repository" />
|
||||
<option name="url" value="https://repository.jboss.org/nexus/content/repositories/public/" />
|
||||
</remote-repository>
|
||||
<remote-repository>
|
||||
<option name="id" value="MavenRepo" />
|
||||
<option name="name" value="MavenRepo" />
|
||||
<option name="url" value="https://repo.maven.apache.org/maven2/" />
|
||||
</remote-repository>
|
||||
<remote-repository>
|
||||
<option name="id" value="maven" />
|
||||
<option name="name" value="maven" />
|
||||
<option name="url" value="http://nexus.astraeus.nl/nexus/content/groups/public" />
|
||||
</remote-repository>
|
||||
<remote-repository>
|
||||
<option name="id" value="maven" />
|
||||
<option name="name" value="maven" />
|
||||
<option name="url" value="https://nexus.astraeus.nl/nexus/content/groups/public" />
|
||||
</remote-repository>
|
||||
<remote-repository>
|
||||
<option name="id" value="BintrayJCenter" />
|
||||
<option name="name" value="BintrayJCenter" />
|
||||
<option name="url" value="https://jcenter.bintray.com/" />
|
||||
</remote-repository>
|
||||
</component>
|
||||
</project>
|
||||
7
.idea/kotlinc.xml
generated
7
.idea/kotlinc.xml
generated
@@ -1,7 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="Kotlin2JsCompilerArguments">
|
||||
<option name="sourceMapEmbedSources" />
|
||||
<option name="sourceMapPrefix" />
|
||||
</component>
|
||||
</project>
|
||||
16
.idea/misc.xml
generated
Normal file
16
.idea/misc.xml
generated
Normal file
@@ -0,0 +1,16 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ExternalStorageConfigurationManager" enabled="true" />
|
||||
<component name="FrameworkDetectionExcludesConfiguration">
|
||||
<file type="web" url="file://$PROJECT_DIR$" />
|
||||
</component>
|
||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_8" default="true" project-jdk-name="1.8" project-jdk-type="JavaSDK" />
|
||||
<component name="accountSettings">
|
||||
<option name="activeRegion" value="us-east-1" />
|
||||
<option name="recentlyUsedRegions">
|
||||
<list>
|
||||
<option value="us-east-1" />
|
||||
</list>
|
||||
</option>
|
||||
</component>
|
||||
</project>
|
||||
8
.idea/modules.xml
generated
8
.idea/modules.xml
generated
@@ -1,8 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ProjectModuleManager">
|
||||
<modules>
|
||||
<module fileurl="file://$PROJECT_DIR$/komp-todo.iml" filepath="$PROJECT_DIR$/komp-todo.iml" group="komp-todo" />
|
||||
</modules>
|
||||
</component>
|
||||
</project>
|
||||
15
.idea/modules/komp-todo.main.iml
generated
Normal file
15
.idea/modules/komp-todo.main.iml
generated
Normal file
@@ -0,0 +1,15 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module external.system.module.type="sourceSet" type="JAVA_MODULE" version="4">
|
||||
<component name="NewModuleRootManager">
|
||||
<output url="file://$MODULE_DIR$/../../build/classes/java/main" />
|
||||
<exclude-output />
|
||||
<content url="file://$MODULE_DIR$/../../src/main">
|
||||
<sourceFolder url="file://$MODULE_DIR$/../../src/main/kotlin" type="kotlin-source" />
|
||||
</content>
|
||||
<orderEntry type="jdk" jdkName="Kotlin SDK" jdkType="KotlinSDK" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
<orderEntry type="library" name="Gradle: org.jetbrains.kotlin:kotlin-stdlib-js:1.4.30" level="project" />
|
||||
<orderEntry type="library" name="Gradle: org.jetbrains.kotlin:kotlin-stdlib-common:1.4.30" level="project" />
|
||||
<orderEntry type="library" name="Gradle: nl.astraeus:komp:0.2.5-SNAPSHOT" level="project" />
|
||||
</component>
|
||||
</module>
|
||||
14
.idea/modules/komp-todo.test.iml
generated
Normal file
14
.idea/modules/komp-todo.test.iml
generated
Normal file
@@ -0,0 +1,14 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module external.system.module.type="sourceSet" type="JAVA_MODULE" version="4">
|
||||
<component name="NewModuleRootManager">
|
||||
<output-test url="file://$MODULE_DIR$/../../build/classes/java/test" />
|
||||
<exclude-output />
|
||||
<content url="file://$MODULE_DIR$/../../src/test" />
|
||||
<orderEntry type="jdk" jdkName="Kotlin SDK" jdkType="KotlinSDK" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
<orderEntry type="module" module-name="komp-todo.main" />
|
||||
<orderEntry type="library" name="Gradle: org.jetbrains.kotlin:kotlin-stdlib-js:1.4.30" level="project" />
|
||||
<orderEntry type="library" name="Gradle: org.jetbrains.kotlin:kotlin-stdlib-common:1.4.30" level="project" />
|
||||
<orderEntry type="library" name="Gradle: nl.astraeus:komp:0.2.5-SNAPSHOT" level="project" />
|
||||
</component>
|
||||
</module>
|
||||
82
build.gradle
82
build.gradle
@@ -1,82 +0,0 @@
|
||||
buildscript {
|
||||
ext.kotlin_version = '1.3.50'
|
||||
|
||||
repositories {
|
||||
jcenter()
|
||||
maven {
|
||||
url "http://nexus.astraeus.nl/nexus/content/groups/public"
|
||||
}
|
||||
maven {
|
||||
url "https://plugins.gradle.org/m2/"
|
||||
}
|
||||
mavenCentral()
|
||||
}
|
||||
dependencies {
|
||||
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
|
||||
classpath "com.eriwen:gradle-js-plugin:1.12.1"
|
||||
}
|
||||
}
|
||||
|
||||
apply plugin: "com.eriwen.gradle.js"
|
||||
apply plugin: 'kotlin-platform-js'
|
||||
apply plugin: 'kotlin-dce-js'
|
||||
|
||||
group 'nl.astraeus'
|
||||
version '0.0.1-SNAPSHOT'
|
||||
|
||||
allprojects {
|
||||
ext {
|
||||
kotlin_version = '1.3.50'
|
||||
}
|
||||
}
|
||||
|
||||
repositories {
|
||||
maven {
|
||||
url "http://nexus.astraeus.nl/nexus/content/groups/public"
|
||||
}
|
||||
mavenCentral()
|
||||
}
|
||||
|
||||
dependencies {
|
||||
compile "org.jetbrains.kotlin:kotlin-stdlib-js:$kotlin_version"
|
||||
compile "nl.astraeus:komp:0.1.9"
|
||||
}
|
||||
|
||||
compileKotlin2Js {
|
||||
kotlinOptions.metaInfo = true
|
||||
|
||||
kotlinOptions.sourceMap = true
|
||||
kotlinOptions.sourceMapEmbedSources = "always"
|
||||
kotlinOptions.suppressWarnings = true
|
||||
kotlinOptions.verbose = true
|
||||
}
|
||||
|
||||
runDceKotlinJs.doLast {
|
||||
copy {
|
||||
from("build/kotlin-js-min/main")
|
||||
|
||||
into("web/js/generated")
|
||||
}
|
||||
}
|
||||
|
||||
// Create new CombineJsTasks if you have multiple sets of JS files
|
||||
combineJs {
|
||||
dependsOn runDceKotlinJs
|
||||
source = [
|
||||
"${projectDir}/web/js/generated/kotlin.js",
|
||||
"${projectDir}/web/js/generated/kotlinx-html-js.js",
|
||||
"${projectDir}/web/js/generated/komp.js",
|
||||
"${projectDir}/web/js/generated/komp-todo.js"
|
||||
]
|
||||
dest = file("${projectDir}/web/js/generated/todo.all.js")
|
||||
}
|
||||
|
||||
minifyJs {
|
||||
dependsOn combineJs
|
||||
source = "${projectDir}/web/js/generated/todo.all.js"
|
||||
dest = file("${projectDir}/web/js/generated/todo.all.min.js")
|
||||
closure {
|
||||
warningLevel = 'QUIET'
|
||||
compilerOptions.languageIn = "ECMASCRIPT5"
|
||||
}
|
||||
}
|
||||
49
build.gradle.kts
Normal file
49
build.gradle.kts
Normal file
@@ -0,0 +1,49 @@
|
||||
|
||||
plugins {
|
||||
kotlin("multiplatform") version "1.4.30"
|
||||
`maven-publish`
|
||||
}
|
||||
|
||||
group = "nl.astraeus"
|
||||
version = "0.1.0-SNAPSHOT"
|
||||
|
||||
repositories {
|
||||
mavenCentral()
|
||||
jcenter()
|
||||
maven {
|
||||
url = uri("http://nexus.astraeus.nl/nexus/content/groups/public")
|
||||
}
|
||||
}
|
||||
|
||||
kotlin {
|
||||
/* Targets configuration omitted.
|
||||
* To find out how to configure the targets, please follow the link:
|
||||
* https://kotlinlang.org/docs/reference/building-mpp-with-gradle.html#setting-up-targets */
|
||||
js(IR) {
|
||||
binaries.executable()
|
||||
browser {
|
||||
//produceKotlinLibrary()
|
||||
testTask {
|
||||
useKarma {
|
||||
useChromeHeadless()
|
||||
}
|
||||
}
|
||||
distribution {
|
||||
directory = File("$projectDir/web/")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sourceSets {
|
||||
val commonMain by getting {
|
||||
dependencies {
|
||||
implementation("nl.astraeus:komp:0.2.5-SNAPSHOT")
|
||||
}
|
||||
}
|
||||
val jsMain by getting {
|
||||
dependencies {
|
||||
implementation(kotlin("stdlib-js"))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
2
gradle/wrapper/gradle-wrapper.properties
vendored
2
gradle/wrapper/gradle-wrapper.properties
vendored
@@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-4.2-all.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-6.2-all.zip
|
||||
|
||||
@@ -1,2 +0,0 @@
|
||||
rootProject.name = 'komp-todo'
|
||||
|
||||
11
settings.gradle.kts
Normal file
11
settings.gradle.kts
Normal file
@@ -0,0 +1,11 @@
|
||||
pluginManagement {
|
||||
repositories {
|
||||
mavenCentral()
|
||||
|
||||
maven { setUrl("https://plugins.gradle.org/m2/") }
|
||||
}
|
||||
}
|
||||
|
||||
rootProject.name = "komp-todo"
|
||||
|
||||
enableFeaturePreview("GRADLE_METADATA")
|
||||
229
src/jsMain/kotlin/nl/astraeus/komp/todo/Todo.kt
Normal file
229
src/jsMain/kotlin/nl/astraeus/komp/todo/Todo.kt
Normal file
@@ -0,0 +1,229 @@
|
||||
package nl.astraeus.komp.todo
|
||||
|
||||
import kotlinx.browser.document
|
||||
import kotlinx.html.*
|
||||
import kotlinx.html.js.onClickFunction
|
||||
import kotlinx.html.js.onDoubleClickFunction
|
||||
import kotlinx.html.js.onKeyPressFunction
|
||||
import nl.astraeus.komp.HtmlBuilder
|
||||
import nl.astraeus.komp.Komponent
|
||||
import nl.astraeus.komp.include
|
||||
import org.w3c.dom.HTMLInputElement
|
||||
import org.w3c.dom.events.Event
|
||||
import org.w3c.dom.events.KeyboardEvent
|
||||
import kotlin.js.Date
|
||||
|
||||
/**
|
||||
* see: https://github.com/tastejs/todomvc/
|
||||
*/
|
||||
|
||||
class Todo(
|
||||
val dataId: String,
|
||||
var title: String,
|
||||
var completed: Boolean = false,
|
||||
var editing: Boolean = false
|
||||
)
|
||||
|
||||
enum class Selection(val title: String) {
|
||||
ALL("All"),
|
||||
ACTIVE("Active"),
|
||||
COMPLETED("Completed")
|
||||
}
|
||||
|
||||
class TodoKomponent(
|
||||
val app: TodoApp,
|
||||
val todo: Todo
|
||||
) : Komponent() {
|
||||
|
||||
override fun HtmlBuilder.render() {
|
||||
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)
|
||||
}
|
||||
}
|
||||
}
|
||||
} 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)
|
||||
}
|
||||
}
|
||||
label(classes = "todo-content") {
|
||||
+todo.title
|
||||
|
||||
onDoubleClickFunction = {
|
||||
app.setEditing(todo)
|
||||
}
|
||||
}
|
||||
button(classes = "destroy") {
|
||||
onClickFunction = {
|
||||
app.destroyTodo(todo)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class TodoApp : Komponent() {
|
||||
val todoList: MutableList<Todo> = ArrayList()
|
||||
var selected: Selection = Selection.ALL
|
||||
|
||||
fun addTodo(e: Event) {
|
||||
val target = e.target
|
||||
|
||||
if (target is HTMLInputElement) {
|
||||
todoList.add(Todo("${Date().getTime()}", target.value))
|
||||
|
||||
requestUpdate()
|
||||
}
|
||||
}
|
||||
|
||||
fun editTodo(e: Event, todo: Todo) {
|
||||
val target = e.target
|
||||
|
||||
if (target is HTMLInputElement) {
|
||||
todo.title = target.value
|
||||
todo.editing = false
|
||||
|
||||
requestUpdate()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
fun destroyTodo(todo: Todo) {
|
||||
todoList.remove(todo)
|
||||
|
||||
requestUpdate()
|
||||
}
|
||||
|
||||
fun selectSelection(selection: Selection) {
|
||||
selected = selection
|
||||
|
||||
requestUpdate()
|
||||
}
|
||||
|
||||
fun clearCompleted() {
|
||||
for (todo in ArrayList(todoList)) {
|
||||
if (todo.completed) {
|
||||
todoList.remove(todo)
|
||||
}
|
||||
}
|
||||
|
||||
requestUpdate()
|
||||
}
|
||||
|
||||
fun todoClicked(todo: Todo) {
|
||||
todo.completed = !todo.completed
|
||||
|
||||
requestUpdate()
|
||||
}
|
||||
|
||||
fun getItemsLeft(): Int {
|
||||
var result = 0
|
||||
for (todo in todoList) {
|
||||
if (!todo.completed) {
|
||||
result++
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
fun setEditing(editTodo: Todo) {
|
||||
for (todo in todoList) {
|
||||
todo.editing = todo == editTodo
|
||||
}
|
||||
|
||||
requestUpdate()
|
||||
}
|
||||
|
||||
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()) {
|
||||
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)) {
|
||||
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 += "selected"
|
||||
}
|
||||
href = "#"
|
||||
+selection.title
|
||||
onClickFunction = {
|
||||
selectSelection(selection)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
button(classes = "clear-completed") {
|
||||
+"Clear completed"
|
||||
onClickFunction = {
|
||||
clearCompleted()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
fun main() {
|
||||
Komponent.create(document.body!!, TodoApp(), true)
|
||||
}
|
||||
@@ -12,6 +12,6 @@
|
||||
<p>Compare other javascript MVC* frameworks with <a href="http://todomvc.com">TodoMVC</a></p>
|
||||
</footer>
|
||||
|
||||
<script src="js/generated/todo.all.min.js" ></script>
|
||||
<script src="komp-todo.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,255 +0,0 @@
|
||||
package nl.astraeus.komp.todo
|
||||
|
||||
import kotlinx.html.HtmlBlockTag
|
||||
import kotlinx.html.InputType
|
||||
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.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.HTMLInputElement
|
||||
import org.w3c.dom.events.Event
|
||||
import org.w3c.dom.events.KeyboardEvent
|
||||
import kotlin.browser.document
|
||||
import kotlin.js.Date
|
||||
|
||||
/**
|
||||
* see: https://github.com/tastejs/todomvc/
|
||||
*/
|
||||
|
||||
class Todo(
|
||||
val dataId: String,
|
||||
var title: String,
|
||||
var completed: Boolean = false,
|
||||
var editing: Boolean = false
|
||||
)
|
||||
|
||||
enum class Selection(val title: String) {
|
||||
ALL("All"),
|
||||
ACTIVE("Active"),
|
||||
COMPLETED("Completed")
|
||||
}
|
||||
|
||||
fun HtmlBlockTag.todo(app: TodoApp, todo: Todo) {
|
||||
this.include(TodoKomponent(app, todo))
|
||||
}
|
||||
|
||||
class TodoKomponent(
|
||||
val app: TodoApp,
|
||||
val todo: Todo
|
||||
) : Komponent() {
|
||||
|
||||
override fun render(consumer: HtmlBuilder) = 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)
|
||||
}
|
||||
}
|
||||
}
|
||||
} 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)
|
||||
}
|
||||
}
|
||||
label(classes = "todo-content") {
|
||||
+todo.title
|
||||
|
||||
onDoubleClickFunction = {
|
||||
app.setEditing(todo)
|
||||
}
|
||||
}
|
||||
button(classes = "destroy") {
|
||||
onClickFunction = {
|
||||
app.destroyTodo(todo)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class TodoApp : Komponent() {
|
||||
val todoList: MutableList<Todo> = ArrayList()
|
||||
var selected: Selection = Selection.ALL
|
||||
|
||||
fun addTodo(e: Event) {
|
||||
val target = e.target
|
||||
|
||||
if (target is HTMLInputElement) {
|
||||
todoList.add(Todo("${Date().getTime()}", target.value))
|
||||
|
||||
refresh()
|
||||
}
|
||||
}
|
||||
|
||||
fun editTodo(e: Event, todo: Todo) {
|
||||
val target = e.target
|
||||
|
||||
if (target is HTMLInputElement) {
|
||||
todo.title = target.value
|
||||
todo.editing = false
|
||||
|
||||
refresh()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
fun destroyTodo(todo: Todo) {
|
||||
todoList.remove(todo)
|
||||
|
||||
refresh()
|
||||
}
|
||||
|
||||
fun selectSelection(selection: Selection) {
|
||||
selected = selection
|
||||
|
||||
refresh()
|
||||
}
|
||||
|
||||
fun clearCompleted() {
|
||||
for (todo in ArrayList(todoList)) {
|
||||
if (todo.completed) {
|
||||
todoList.remove(todo)
|
||||
}
|
||||
}
|
||||
|
||||
refresh()
|
||||
}
|
||||
|
||||
fun todoClicked(todo: Todo) {
|
||||
todo.completed = !todo.completed
|
||||
|
||||
refresh()
|
||||
}
|
||||
|
||||
fun getItemsLeft(): Int {
|
||||
var result = 0
|
||||
for (todo in todoList) {
|
||||
if (!todo.completed) {
|
||||
result++
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
fun setEditing(editTodo: Todo) {
|
||||
for (todo in todoList) {
|
||||
todo.editing = todo == editTodo
|
||||
}
|
||||
|
||||
refresh()
|
||||
}
|
||||
|
||||
override fun refresh() {
|
||||
super.refresh()
|
||||
|
||||
val inputBox = document.getElementById("todo_input")
|
||||
|
||||
if (inputBox is HTMLInputElement) {
|
||||
inputBox.focus()
|
||||
}
|
||||
}
|
||||
|
||||
override fun render(consumer: HtmlBuilder) = 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"
|
||||
onClickFunction = {
|
||||
clearCompleted()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
fun main() {
|
||||
Komponent.create(document.body!!, TodoApp(), true)
|
||||
}
|
||||
@@ -1,20 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Komp-Todo</title>
|
||||
<link rel="stylesheet" href="css/index.css">
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<footer class="info">
|
||||
<p>Double-click to edit a todo</p>
|
||||
<p>Compare other javascript MVC* frameworks with <a href="http://todomvc.com">TodoMVC</a></p>
|
||||
</footer>
|
||||
|
||||
<script src="js/generated/kotlin.js" ></script>
|
||||
<script src="js/generated/kotlinx-html-js.js" ></script>
|
||||
<script src="js/generated/komp.js" ></script>
|
||||
<script src="js/generated/komp-todo.js" ></script>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user