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">
|
<component name="GradleSettings">
|
||||||
<option name="linkedExternalProjectsSettings">
|
<option name="linkedExternalProjectsSettings">
|
||||||
<GradleProjectSettings>
|
<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="externalProjectPath" value="$PROJECT_DIR$" />
|
||||||
|
<option name="gradleJvm" value="1.8" />
|
||||||
<option name="modules">
|
<option name="modules">
|
||||||
<set>
|
<set>
|
||||||
<option value="$PROJECT_DIR$" />
|
<option value="$PROJECT_DIR$" />
|
||||||
</set>
|
</set>
|
||||||
</option>
|
</option>
|
||||||
<option name="resolveModulePerSourceSet" value="false" />
|
|
||||||
<option name="useAutoImport" value="true" />
|
|
||||||
</GradleProjectSettings>
|
</GradleProjectSettings>
|
||||||
</option>
|
</option>
|
||||||
</component>
|
</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
|
distributionPath=wrapper/dists
|
||||||
zipStoreBase=GRADLE_USER_HOME
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
zipStorePath=wrapper/dists
|
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>
|
<p>Compare other javascript MVC* frameworks with <a href="http://todomvc.com">TodoMVC</a></p>
|
||||||
</footer>
|
</footer>
|
||||||
|
|
||||||
<script src="js/generated/todo.all.min.js" ></script>
|
<script src="komp-todo.js"></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</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