diff --git a/build.gradle.kts b/build.gradle.kts index 1b49d69..ac68b54 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -6,7 +6,7 @@ } group = "nl.astraeus" -version = "1.0.0" +version = "1.0.1-SNAPSHOT" repositories { mavenCentral() diff --git a/build.gradle.kts b/build.gradle.kts index 1b49d69..ac68b54 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -6,7 +6,7 @@ } group = "nl.astraeus" -version = "1.0.0" +version = "1.0.1-SNAPSHOT" repositories { mavenCentral() diff --git a/docs/getting-started.md b/docs/getting-started.md new file mode 100644 index 0000000..73b8291 --- /dev/null +++ b/docs/getting-started.md @@ -0,0 +1,136 @@ +# Table of contents + +[home](home.md) +[getting started](getting-started.md) + +# Getting started + +To get started create a new kotlin project in intellij of the type 'Browser application' + +![Create 'Browser Application' project](/docs/img/create-project.png "Create 'Browser Application' project") + +Add the 'sourceSets' block with the kotlin-komponent dependency so your build.gradle.kts looks like this: + +```gradle +plugins { + kotlin("js") version "1.6.10" +} + +group = "com.test" +version = "1.0.0-SNAPSHOT" + +repositories { + mavenCentral() +} + +dependencies { + api("nl.astraeus:kotlin-komponent-js:1.0.0") + + testImplementation(kotlin("test")) +} + +kotlin { + js(IR) { + binaries.executable() + browser { + commonWebpackConfig { + cssSupport.enabled = true + } + } + } +} +``` + +Refresh the gradle project to import the dependency. + +There is now only one kt file in the project called Simple.kt, it should look like this: + +```kotin +fun main() { + console.log("Hello, ${greet()}") +} + +fun greet() = "world" +``` + +Replace the code in the file with the following for a simple click app: + +```koltin +import kotlinx.browser.document +import kotlinx.html.button +import kotlinx.html.div +import kotlinx.html.hr +import kotlinx.html.js.onClickFunction +import nl.astraeus.komp.HtmlBuilder +import nl.astraeus.komp.Komponent +import nl.astraeus.komp.mutableCollectionState +import nl.astraeus.komp.state +import kotlin.js.Date + +fun main() { + console.log("Hello, ${greet()}") + + Komponent.create(document.body!!, TestKomponent()) +} + +fun greet() = "world" + +class TestKomponent : Komponent() { + var clicks: Int = 0 + val lines: MutableCollection = mutableListOf() + + override fun HtmlBuilder.render() { + div { + div { + +"Hello Komponent!" + } + + div { + +"Clicks $clicks" + } + + div { + button { + +"Click" + onClickFunction = { + clicks++ + lines.add("click $clicks at ${Date()}") + requestUpdate() + } + } + } + + hr() + + for (line in lines) { + div { + + line + } + } + + } + } +} +``` + +First in the main we add our TestKomponent to the document body with the following line: + +```kotlin + Komponent.create(document.body!!, TestKomponent()) +``` + +The TestKomponent.render method will be called to render our Komponent. +As you can see events can be attached inline with the onFunction methods. +The requestUpdate method will call the render method again and update the page accordingly. + +If you like you can use some helpers that will automatically call the requestUpdate method if +the data changes, that would look like this: + +```kotlin + var clicks: Int by state(0) + val lines: MutableCollection = mutableCollectionState(mutableListOf()) +``` + +In that case you can remove the requestUpdate call from the onClickFunction. + +You can find a working repository of this example here: [example]() diff --git a/build.gradle.kts b/build.gradle.kts index 1b49d69..ac68b54 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -6,7 +6,7 @@ } group = "nl.astraeus" -version = "1.0.0" +version = "1.0.1-SNAPSHOT" repositories { mavenCentral() diff --git a/docs/getting-started.md b/docs/getting-started.md new file mode 100644 index 0000000..73b8291 --- /dev/null +++ b/docs/getting-started.md @@ -0,0 +1,136 @@ +# Table of contents + +[home](home.md) +[getting started](getting-started.md) + +# Getting started + +To get started create a new kotlin project in intellij of the type 'Browser application' + +![Create 'Browser Application' project](/docs/img/create-project.png "Create 'Browser Application' project") + +Add the 'sourceSets' block with the kotlin-komponent dependency so your build.gradle.kts looks like this: + +```gradle +plugins { + kotlin("js") version "1.6.10" +} + +group = "com.test" +version = "1.0.0-SNAPSHOT" + +repositories { + mavenCentral() +} + +dependencies { + api("nl.astraeus:kotlin-komponent-js:1.0.0") + + testImplementation(kotlin("test")) +} + +kotlin { + js(IR) { + binaries.executable() + browser { + commonWebpackConfig { + cssSupport.enabled = true + } + } + } +} +``` + +Refresh the gradle project to import the dependency. + +There is now only one kt file in the project called Simple.kt, it should look like this: + +```kotin +fun main() { + console.log("Hello, ${greet()}") +} + +fun greet() = "world" +``` + +Replace the code in the file with the following for a simple click app: + +```koltin +import kotlinx.browser.document +import kotlinx.html.button +import kotlinx.html.div +import kotlinx.html.hr +import kotlinx.html.js.onClickFunction +import nl.astraeus.komp.HtmlBuilder +import nl.astraeus.komp.Komponent +import nl.astraeus.komp.mutableCollectionState +import nl.astraeus.komp.state +import kotlin.js.Date + +fun main() { + console.log("Hello, ${greet()}") + + Komponent.create(document.body!!, TestKomponent()) +} + +fun greet() = "world" + +class TestKomponent : Komponent() { + var clicks: Int = 0 + val lines: MutableCollection = mutableListOf() + + override fun HtmlBuilder.render() { + div { + div { + +"Hello Komponent!" + } + + div { + +"Clicks $clicks" + } + + div { + button { + +"Click" + onClickFunction = { + clicks++ + lines.add("click $clicks at ${Date()}") + requestUpdate() + } + } + } + + hr() + + for (line in lines) { + div { + + line + } + } + + } + } +} +``` + +First in the main we add our TestKomponent to the document body with the following line: + +```kotlin + Komponent.create(document.body!!, TestKomponent()) +``` + +The TestKomponent.render method will be called to render our Komponent. +As you can see events can be attached inline with the onFunction methods. +The requestUpdate method will call the render method again and update the page accordingly. + +If you like you can use some helpers that will automatically call the requestUpdate method if +the data changes, that would look like this: + +```kotlin + var clicks: Int by state(0) + val lines: MutableCollection = mutableCollectionState(mutableListOf()) +``` + +In that case you can remove the requestUpdate call from the onClickFunction. + +You can find a working repository of this example here: [example]() diff --git a/docs/home.md b/docs/home.md new file mode 100644 index 0000000..94ae22a --- /dev/null +++ b/docs/home.md @@ -0,0 +1,4 @@ +# Table of contents + +[home](home.md) +[getting started](getting-started.md) diff --git a/build.gradle.kts b/build.gradle.kts index 1b49d69..ac68b54 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -6,7 +6,7 @@ } group = "nl.astraeus" -version = "1.0.0" +version = "1.0.1-SNAPSHOT" repositories { mavenCentral() diff --git a/docs/getting-started.md b/docs/getting-started.md new file mode 100644 index 0000000..73b8291 --- /dev/null +++ b/docs/getting-started.md @@ -0,0 +1,136 @@ +# Table of contents + +[home](home.md) +[getting started](getting-started.md) + +# Getting started + +To get started create a new kotlin project in intellij of the type 'Browser application' + +![Create 'Browser Application' project](/docs/img/create-project.png "Create 'Browser Application' project") + +Add the 'sourceSets' block with the kotlin-komponent dependency so your build.gradle.kts looks like this: + +```gradle +plugins { + kotlin("js") version "1.6.10" +} + +group = "com.test" +version = "1.0.0-SNAPSHOT" + +repositories { + mavenCentral() +} + +dependencies { + api("nl.astraeus:kotlin-komponent-js:1.0.0") + + testImplementation(kotlin("test")) +} + +kotlin { + js(IR) { + binaries.executable() + browser { + commonWebpackConfig { + cssSupport.enabled = true + } + } + } +} +``` + +Refresh the gradle project to import the dependency. + +There is now only one kt file in the project called Simple.kt, it should look like this: + +```kotin +fun main() { + console.log("Hello, ${greet()}") +} + +fun greet() = "world" +``` + +Replace the code in the file with the following for a simple click app: + +```koltin +import kotlinx.browser.document +import kotlinx.html.button +import kotlinx.html.div +import kotlinx.html.hr +import kotlinx.html.js.onClickFunction +import nl.astraeus.komp.HtmlBuilder +import nl.astraeus.komp.Komponent +import nl.astraeus.komp.mutableCollectionState +import nl.astraeus.komp.state +import kotlin.js.Date + +fun main() { + console.log("Hello, ${greet()}") + + Komponent.create(document.body!!, TestKomponent()) +} + +fun greet() = "world" + +class TestKomponent : Komponent() { + var clicks: Int = 0 + val lines: MutableCollection = mutableListOf() + + override fun HtmlBuilder.render() { + div { + div { + +"Hello Komponent!" + } + + div { + +"Clicks $clicks" + } + + div { + button { + +"Click" + onClickFunction = { + clicks++ + lines.add("click $clicks at ${Date()}") + requestUpdate() + } + } + } + + hr() + + for (line in lines) { + div { + + line + } + } + + } + } +} +``` + +First in the main we add our TestKomponent to the document body with the following line: + +```kotlin + Komponent.create(document.body!!, TestKomponent()) +``` + +The TestKomponent.render method will be called to render our Komponent. +As you can see events can be attached inline with the onFunction methods. +The requestUpdate method will call the render method again and update the page accordingly. + +If you like you can use some helpers that will automatically call the requestUpdate method if +the data changes, that would look like this: + +```kotlin + var clicks: Int by state(0) + val lines: MutableCollection = mutableCollectionState(mutableListOf()) +``` + +In that case you can remove the requestUpdate call from the onClickFunction. + +You can find a working repository of this example here: [example]() diff --git a/docs/home.md b/docs/home.md new file mode 100644 index 0000000..94ae22a --- /dev/null +++ b/docs/home.md @@ -0,0 +1,4 @@ +# Table of contents + +[home](home.md) +[getting started](getting-started.md) diff --git a/docs/img/create project.png b/docs/img/create project.png new file mode 100644 index 0000000..b078603 --- /dev/null +++ b/docs/img/create project.png Binary files differ diff --git a/build.gradle.kts b/build.gradle.kts index 1b49d69..ac68b54 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -6,7 +6,7 @@ } group = "nl.astraeus" -version = "1.0.0" +version = "1.0.1-SNAPSHOT" repositories { mavenCentral() diff --git a/docs/getting-started.md b/docs/getting-started.md new file mode 100644 index 0000000..73b8291 --- /dev/null +++ b/docs/getting-started.md @@ -0,0 +1,136 @@ +# Table of contents + +[home](home.md) +[getting started](getting-started.md) + +# Getting started + +To get started create a new kotlin project in intellij of the type 'Browser application' + +![Create 'Browser Application' project](/docs/img/create-project.png "Create 'Browser Application' project") + +Add the 'sourceSets' block with the kotlin-komponent dependency so your build.gradle.kts looks like this: + +```gradle +plugins { + kotlin("js") version "1.6.10" +} + +group = "com.test" +version = "1.0.0-SNAPSHOT" + +repositories { + mavenCentral() +} + +dependencies { + api("nl.astraeus:kotlin-komponent-js:1.0.0") + + testImplementation(kotlin("test")) +} + +kotlin { + js(IR) { + binaries.executable() + browser { + commonWebpackConfig { + cssSupport.enabled = true + } + } + } +} +``` + +Refresh the gradle project to import the dependency. + +There is now only one kt file in the project called Simple.kt, it should look like this: + +```kotin +fun main() { + console.log("Hello, ${greet()}") +} + +fun greet() = "world" +``` + +Replace the code in the file with the following for a simple click app: + +```koltin +import kotlinx.browser.document +import kotlinx.html.button +import kotlinx.html.div +import kotlinx.html.hr +import kotlinx.html.js.onClickFunction +import nl.astraeus.komp.HtmlBuilder +import nl.astraeus.komp.Komponent +import nl.astraeus.komp.mutableCollectionState +import nl.astraeus.komp.state +import kotlin.js.Date + +fun main() { + console.log("Hello, ${greet()}") + + Komponent.create(document.body!!, TestKomponent()) +} + +fun greet() = "world" + +class TestKomponent : Komponent() { + var clicks: Int = 0 + val lines: MutableCollection = mutableListOf() + + override fun HtmlBuilder.render() { + div { + div { + +"Hello Komponent!" + } + + div { + +"Clicks $clicks" + } + + div { + button { + +"Click" + onClickFunction = { + clicks++ + lines.add("click $clicks at ${Date()}") + requestUpdate() + } + } + } + + hr() + + for (line in lines) { + div { + + line + } + } + + } + } +} +``` + +First in the main we add our TestKomponent to the document body with the following line: + +```kotlin + Komponent.create(document.body!!, TestKomponent()) +``` + +The TestKomponent.render method will be called to render our Komponent. +As you can see events can be attached inline with the onFunction methods. +The requestUpdate method will call the render method again and update the page accordingly. + +If you like you can use some helpers that will automatically call the requestUpdate method if +the data changes, that would look like this: + +```kotlin + var clicks: Int by state(0) + val lines: MutableCollection = mutableCollectionState(mutableListOf()) +``` + +In that case you can remove the requestUpdate call from the onClickFunction. + +You can find a working repository of this example here: [example]() diff --git a/docs/home.md b/docs/home.md new file mode 100644 index 0000000..94ae22a --- /dev/null +++ b/docs/home.md @@ -0,0 +1,4 @@ +# Table of contents + +[home](home.md) +[getting started](getting-started.md) diff --git a/docs/img/create project.png b/docs/img/create project.png new file mode 100644 index 0000000..b078603 --- /dev/null +++ b/docs/img/create project.png Binary files differ diff --git a/docs/img/new-project-simple.png b/docs/img/new-project-simple.png new file mode 100644 index 0000000..b0a3ab2 --- /dev/null +++ b/docs/img/new-project-simple.png Binary files differ diff --git a/build.gradle.kts b/build.gradle.kts index 1b49d69..ac68b54 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -6,7 +6,7 @@ } group = "nl.astraeus" -version = "1.0.0" +version = "1.0.1-SNAPSHOT" repositories { mavenCentral() diff --git a/docs/getting-started.md b/docs/getting-started.md new file mode 100644 index 0000000..73b8291 --- /dev/null +++ b/docs/getting-started.md @@ -0,0 +1,136 @@ +# Table of contents + +[home](home.md) +[getting started](getting-started.md) + +# Getting started + +To get started create a new kotlin project in intellij of the type 'Browser application' + +![Create 'Browser Application' project](/docs/img/create-project.png "Create 'Browser Application' project") + +Add the 'sourceSets' block with the kotlin-komponent dependency so your build.gradle.kts looks like this: + +```gradle +plugins { + kotlin("js") version "1.6.10" +} + +group = "com.test" +version = "1.0.0-SNAPSHOT" + +repositories { + mavenCentral() +} + +dependencies { + api("nl.astraeus:kotlin-komponent-js:1.0.0") + + testImplementation(kotlin("test")) +} + +kotlin { + js(IR) { + binaries.executable() + browser { + commonWebpackConfig { + cssSupport.enabled = true + } + } + } +} +``` + +Refresh the gradle project to import the dependency. + +There is now only one kt file in the project called Simple.kt, it should look like this: + +```kotin +fun main() { + console.log("Hello, ${greet()}") +} + +fun greet() = "world" +``` + +Replace the code in the file with the following for a simple click app: + +```koltin +import kotlinx.browser.document +import kotlinx.html.button +import kotlinx.html.div +import kotlinx.html.hr +import kotlinx.html.js.onClickFunction +import nl.astraeus.komp.HtmlBuilder +import nl.astraeus.komp.Komponent +import nl.astraeus.komp.mutableCollectionState +import nl.astraeus.komp.state +import kotlin.js.Date + +fun main() { + console.log("Hello, ${greet()}") + + Komponent.create(document.body!!, TestKomponent()) +} + +fun greet() = "world" + +class TestKomponent : Komponent() { + var clicks: Int = 0 + val lines: MutableCollection = mutableListOf() + + override fun HtmlBuilder.render() { + div { + div { + +"Hello Komponent!" + } + + div { + +"Clicks $clicks" + } + + div { + button { + +"Click" + onClickFunction = { + clicks++ + lines.add("click $clicks at ${Date()}") + requestUpdate() + } + } + } + + hr() + + for (line in lines) { + div { + + line + } + } + + } + } +} +``` + +First in the main we add our TestKomponent to the document body with the following line: + +```kotlin + Komponent.create(document.body!!, TestKomponent()) +``` + +The TestKomponent.render method will be called to render our Komponent. +As you can see events can be attached inline with the onFunction methods. +The requestUpdate method will call the render method again and update the page accordingly. + +If you like you can use some helpers that will automatically call the requestUpdate method if +the data changes, that would look like this: + +```kotlin + var clicks: Int by state(0) + val lines: MutableCollection = mutableCollectionState(mutableListOf()) +``` + +In that case you can remove the requestUpdate call from the onClickFunction. + +You can find a working repository of this example here: [example]() diff --git a/docs/home.md b/docs/home.md new file mode 100644 index 0000000..94ae22a --- /dev/null +++ b/docs/home.md @@ -0,0 +1,4 @@ +# Table of contents + +[home](home.md) +[getting started](getting-started.md) diff --git a/docs/img/create project.png b/docs/img/create project.png new file mode 100644 index 0000000..b078603 --- /dev/null +++ b/docs/img/create project.png Binary files differ diff --git a/docs/img/new-project-simple.png b/docs/img/new-project-simple.png new file mode 100644 index 0000000..b0a3ab2 --- /dev/null +++ b/docs/img/new-project-simple.png Binary files differ diff --git a/src/jsMain/kotlin/nl/astraeus/komp/MutableCollectionStateDelegate.kt b/src/jsMain/kotlin/nl/astraeus/komp/MutableCollectionStateDelegate.kt new file mode 100644 index 0000000..c2743b2 --- /dev/null +++ b/src/jsMain/kotlin/nl/astraeus/komp/MutableCollectionStateDelegate.kt @@ -0,0 +1,54 @@ +package nl.astraeus.komp + +inline fun Komponent.mutableCollectionState( + initialValue: MutableCollection +): MutableCollection = MutableCollectionStateDelegate( + this, + initialValue +) + +class MutableCollectionStateDelegate( + val komponent: Komponent, + val collection: MutableCollection +): MutableCollection by collection { + + override fun add(element: T): Boolean { + komponent.requestUpdate() + + return collection.add(element) + } + + override fun addAll(elements: Collection): Boolean { + komponent.requestUpdate() + + return collection.addAll(elements) + } + + override fun clear() { + komponent.requestUpdate() + + collection.clear() + } + + // todo: return iterator wrapper to update at changes? + // override fun iterator(): MutableIterator = collection.iterator() + + override fun remove(element: T): Boolean { + komponent.requestUpdate() + + return collection.remove(element) + } + + override fun removeAll(elements: Collection): Boolean { + komponent.requestUpdate() + + return collection.removeAll(elements) + } + + override fun retainAll(elements: Collection): Boolean { + komponent.requestUpdate() + + return collection.retainAll(elements) + } + +} diff --git a/build.gradle.kts b/build.gradle.kts index 1b49d69..ac68b54 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -6,7 +6,7 @@ } group = "nl.astraeus" -version = "1.0.0" +version = "1.0.1-SNAPSHOT" repositories { mavenCentral() diff --git a/docs/getting-started.md b/docs/getting-started.md new file mode 100644 index 0000000..73b8291 --- /dev/null +++ b/docs/getting-started.md @@ -0,0 +1,136 @@ +# Table of contents + +[home](home.md) +[getting started](getting-started.md) + +# Getting started + +To get started create a new kotlin project in intellij of the type 'Browser application' + +![Create 'Browser Application' project](/docs/img/create-project.png "Create 'Browser Application' project") + +Add the 'sourceSets' block with the kotlin-komponent dependency so your build.gradle.kts looks like this: + +```gradle +plugins { + kotlin("js") version "1.6.10" +} + +group = "com.test" +version = "1.0.0-SNAPSHOT" + +repositories { + mavenCentral() +} + +dependencies { + api("nl.astraeus:kotlin-komponent-js:1.0.0") + + testImplementation(kotlin("test")) +} + +kotlin { + js(IR) { + binaries.executable() + browser { + commonWebpackConfig { + cssSupport.enabled = true + } + } + } +} +``` + +Refresh the gradle project to import the dependency. + +There is now only one kt file in the project called Simple.kt, it should look like this: + +```kotin +fun main() { + console.log("Hello, ${greet()}") +} + +fun greet() = "world" +``` + +Replace the code in the file with the following for a simple click app: + +```koltin +import kotlinx.browser.document +import kotlinx.html.button +import kotlinx.html.div +import kotlinx.html.hr +import kotlinx.html.js.onClickFunction +import nl.astraeus.komp.HtmlBuilder +import nl.astraeus.komp.Komponent +import nl.astraeus.komp.mutableCollectionState +import nl.astraeus.komp.state +import kotlin.js.Date + +fun main() { + console.log("Hello, ${greet()}") + + Komponent.create(document.body!!, TestKomponent()) +} + +fun greet() = "world" + +class TestKomponent : Komponent() { + var clicks: Int = 0 + val lines: MutableCollection = mutableListOf() + + override fun HtmlBuilder.render() { + div { + div { + +"Hello Komponent!" + } + + div { + +"Clicks $clicks" + } + + div { + button { + +"Click" + onClickFunction = { + clicks++ + lines.add("click $clicks at ${Date()}") + requestUpdate() + } + } + } + + hr() + + for (line in lines) { + div { + + line + } + } + + } + } +} +``` + +First in the main we add our TestKomponent to the document body with the following line: + +```kotlin + Komponent.create(document.body!!, TestKomponent()) +``` + +The TestKomponent.render method will be called to render our Komponent. +As you can see events can be attached inline with the onFunction methods. +The requestUpdate method will call the render method again and update the page accordingly. + +If you like you can use some helpers that will automatically call the requestUpdate method if +the data changes, that would look like this: + +```kotlin + var clicks: Int by state(0) + val lines: MutableCollection = mutableCollectionState(mutableListOf()) +``` + +In that case you can remove the requestUpdate call from the onClickFunction. + +You can find a working repository of this example here: [example]() diff --git a/docs/home.md b/docs/home.md new file mode 100644 index 0000000..94ae22a --- /dev/null +++ b/docs/home.md @@ -0,0 +1,4 @@ +# Table of contents + +[home](home.md) +[getting started](getting-started.md) diff --git a/docs/img/create project.png b/docs/img/create project.png new file mode 100644 index 0000000..b078603 --- /dev/null +++ b/docs/img/create project.png Binary files differ diff --git a/docs/img/new-project-simple.png b/docs/img/new-project-simple.png new file mode 100644 index 0000000..b0a3ab2 --- /dev/null +++ b/docs/img/new-project-simple.png Binary files differ diff --git a/src/jsMain/kotlin/nl/astraeus/komp/MutableCollectionStateDelegate.kt b/src/jsMain/kotlin/nl/astraeus/komp/MutableCollectionStateDelegate.kt new file mode 100644 index 0000000..c2743b2 --- /dev/null +++ b/src/jsMain/kotlin/nl/astraeus/komp/MutableCollectionStateDelegate.kt @@ -0,0 +1,54 @@ +package nl.astraeus.komp + +inline fun Komponent.mutableCollectionState( + initialValue: MutableCollection +): MutableCollection = MutableCollectionStateDelegate( + this, + initialValue +) + +class MutableCollectionStateDelegate( + val komponent: Komponent, + val collection: MutableCollection +): MutableCollection by collection { + + override fun add(element: T): Boolean { + komponent.requestUpdate() + + return collection.add(element) + } + + override fun addAll(elements: Collection): Boolean { + komponent.requestUpdate() + + return collection.addAll(elements) + } + + override fun clear() { + komponent.requestUpdate() + + collection.clear() + } + + // todo: return iterator wrapper to update at changes? + // override fun iterator(): MutableIterator = collection.iterator() + + override fun remove(element: T): Boolean { + komponent.requestUpdate() + + return collection.remove(element) + } + + override fun removeAll(elements: Collection): Boolean { + komponent.requestUpdate() + + return collection.removeAll(elements) + } + + override fun retainAll(elements: Collection): Boolean { + komponent.requestUpdate() + + return collection.retainAll(elements) + } + +} diff --git a/src/jsMain/kotlin/nl/astraeus/komp/State.kt b/src/jsMain/kotlin/nl/astraeus/komp/State.kt index 37e0ee5..0be1248 100644 --- a/src/jsMain/kotlin/nl/astraeus/komp/State.kt +++ b/src/jsMain/kotlin/nl/astraeus/komp/State.kt @@ -2,20 +2,41 @@ import kotlin.reflect.KProperty -class StateDelegate( - val komponent: Komponent, - initialValue: T -) { - var value: T = initialValue +interface Delegate { operator fun getValue( thisRef: Any?, property: KProperty<*> + ): T + + operator fun setValue( + thisRef: Any?, + property: KProperty<*>, + value: T + ) +} + + +open class StateDelegate( + val komponent: Komponent, + initialValue: T +) : Delegate { + private var value: T = initialValue + + init { + if (value is MutableCollection<*>) { + error("Use mutableList to create a collection!") + } + } + + override operator fun getValue( + thisRef: Any?, + property: KProperty<*> ): T { return value } - operator fun setValue( + override operator fun setValue( thisRef: Any?, property: KProperty<*>, value: T @@ -29,7 +50,7 @@ inline fun Komponent.state( initialValue: T -): StateDelegate = StateDelegate( - this, - initialValue -) +): Delegate = StateDelegate( + this, + initialValue + )