From f6a3657519125ba2f49b7dd6c7748b336007b079 Mon Sep 17 00:00:00 2001 From: Steyn Geldenhuys Date: Fri, 19 Jul 2024 07:30:16 +0200 Subject: [PATCH 1/4] Add WasmJs support to the library section and a basic demo app showing functionality. --- colorpicker-compose/build.gradle.kts | 7 ++ gradle.properties | 1 + gradle/libs.versions.toml | 2 +- settings.gradle.kts | 4 +- wasmApp/build.gradle.kts | 47 +++++++++++++ wasmApp/src/commonMain/kotlin/PickColour.kt | 74 +++++++++++++++++++++ wasmApp/src/wasmJsMain/kotlin/Main.kt | 10 +++ wasmApp/src/wasmJsMain/resources/index.html | 12 ++++ wasmApp/src/wasmJsMain/resources/style.css | 7 ++ 9 files changed, 162 insertions(+), 2 deletions(-) create mode 100644 wasmApp/build.gradle.kts create mode 100644 wasmApp/src/commonMain/kotlin/PickColour.kt create mode 100644 wasmApp/src/wasmJsMain/kotlin/Main.kt create mode 100644 wasmApp/src/wasmJsMain/resources/index.html create mode 100644 wasmApp/src/wasmJsMain/resources/style.css diff --git a/colorpicker-compose/build.gradle.kts b/colorpicker-compose/build.gradle.kts index 66f2660..ebc5b53 100644 --- a/colorpicker-compose/build.gradle.kts +++ b/colorpicker-compose/build.gradle.kts @@ -1,4 +1,5 @@ import com.github.skydoves.colorpicker.compose.Configuration +import org.jetbrains.kotlin.gradle.targets.js.dsl.ExperimentalWasmDsl @Suppress("DSL_SCOPE_VIOLATION") plugins { @@ -39,6 +40,11 @@ kotlin { browser() nodejs() } + @OptIn(ExperimentalWasmDsl::class) + wasmJs { + binaries.library() + } + @Suppress("OPT_IN_USAGE") applyHierarchyTemplate { common { @@ -61,6 +67,7 @@ kotlin { } } withJs() + withWasmJs() } } } diff --git a/gradle.properties b/gradle.properties index c4be87a..80bdfa3 100644 --- a/gradle.properties +++ b/gradle.properties @@ -56,6 +56,7 @@ kotlin.native.cacheKind=none org.jetbrains.compose.experimental.uikit.enabled=true org.jetbrains.compose.experimental.macos.enabled=true org.jetbrains.compose.experimental.jscanvas.enabled=true +org.jetbrains.compose.experimental.wasm.enabled=true compose.kotlin.native.manageCacheKind=false # Required to publish to Nexus (see https://github.com/gradle/gradle/issues/11308) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 61080de..64dcd73 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -1,5 +1,5 @@ [versions] -agp = "8.4.2" +agp = "8.2.0" dokka = "1.9.10" nexusPlugin = "0.29.0" kotlin = "2.0.0" diff --git a/settings.gradle.kts b/settings.gradle.kts index 360a3c9..87dd378 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -6,7 +6,8 @@ pluginManagement { } } dependencyResolutionManagement { - repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS) + // This causes WASM builds to fail with `Could not determine the dependencies of task ':kotlinNodeJsSetup'.` + // repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS) repositories { google() mavenCentral() @@ -16,3 +17,4 @@ rootProject.name = "ColorPickerComposeDemo" include(":app") include(":colorpicker-compose") include(":benchmark") +include("wasmApp") diff --git a/wasmApp/build.gradle.kts b/wasmApp/build.gradle.kts new file mode 100644 index 0000000..e844552 --- /dev/null +++ b/wasmApp/build.gradle.kts @@ -0,0 +1,47 @@ +import org.jetbrains.kotlin.gradle.targets.js.dsl.ExperimentalWasmDsl +import org.jetbrains.kotlin.gradle.targets.js.webpack.KotlinWebpackConfig + +@Suppress("DSL_SCOPE_VIOLATION") +plugins { + id(libs.plugins.kotlin.multiplatform.get().pluginId) + id(libs.plugins.jetbrains.compose.get().pluginId) + id(libs.plugins.compose.compiler.get().pluginId) +} + +kotlin { + @OptIn(ExperimentalWasmDsl::class) + wasmJs { + moduleName = "wasm-demo" + browser { + commonWebpackConfig { + outputFileName = "composeApp.js" + devServer = (devServer ?: KotlinWebpackConfig.DevServer()).apply { + static = (static ?: mutableListOf()).apply { + // Serve sources to debug inside browser + add(project.projectDir.path) + } + } + } + } + binaries.executable() + } + + sourceSets { + commonMain.dependencies { + implementation(compose.runtime) + implementation(compose.foundation) + implementation(compose.ui) + implementation(compose.components.uiToolingPreview) + implementation(compose.material) + implementation(compose.components.resources) + + implementation(project(":colorpicker-compose")) + } + } +} + +tasks.withType().configureEach { + compilerOptions { + jvmTarget.set(org.jetbrains.kotlin.gradle.dsl.JvmTarget.JVM_11) + } +} diff --git a/wasmApp/src/commonMain/kotlin/PickColour.kt b/wasmApp/src/commonMain/kotlin/PickColour.kt new file mode 100644 index 0000000..bc61f3e --- /dev/null +++ b/wasmApp/src/commonMain/kotlin/PickColour.kt @@ -0,0 +1,74 @@ +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.* +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.foundation.text.selection.SelectionContainer +import androidx.compose.material.Text +import androidx.compose.runtime.* +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.clip +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.unit.dp +import com.github.skydoves.colorpicker.compose.* + +@Composable +fun PickColour() { + val controller = rememberColorPickerController() + var currentColorEnvelope by remember { + mutableStateOf( + ColorEnvelope( + Color.Green, + "ff00ff00", + false + ) + ) + } + + Column( + modifier = Modifier.fillMaxSize().background(Color.Black), + horizontalAlignment = Alignment.CenterHorizontally + ) { + HsvColorPicker( + initialColor = currentColorEnvelope.color, + modifier = Modifier.padding(10.dp).size(300.dp), + controller = controller, + onColorChanged = { colorEnvelope: ColorEnvelope -> + currentColorEnvelope = colorEnvelope + } + ) + + Spacer(Modifier.height(8.dp)) + + AlphaSlider( + modifier = Modifier + .height(35.dp) + .width(400.dp), + controller = controller, + ) + + Spacer(Modifier.height(8.dp)) + + BrightnessSlider( + modifier = Modifier + .height(35.dp) + .width(400.dp), + controller = controller, + ) + + Spacer(Modifier.height(8.dp)) + + SelectionContainer { + Text( + currentColorEnvelope.hexCode, + color = currentColorEnvelope.color + ) + } + + AlphaTile( + modifier = Modifier + .size(80.dp) + .clip(RoundedCornerShape(6.dp)), + controller = controller + ) + } +} diff --git a/wasmApp/src/wasmJsMain/kotlin/Main.kt b/wasmApp/src/wasmJsMain/kotlin/Main.kt new file mode 100644 index 0000000..d88f689 --- /dev/null +++ b/wasmApp/src/wasmJsMain/kotlin/Main.kt @@ -0,0 +1,10 @@ +import androidx.compose.ui.ExperimentalComposeUiApi +import androidx.compose.ui.window.ComposeViewport +import kotlinx.browser.document + +@OptIn(ExperimentalComposeUiApi::class) +fun main() { + ComposeViewport(document.body!!) { + PickColour() + } +} diff --git a/wasmApp/src/wasmJsMain/resources/index.html b/wasmApp/src/wasmJsMain/resources/index.html new file mode 100644 index 0000000..68da9ee --- /dev/null +++ b/wasmApp/src/wasmJsMain/resources/index.html @@ -0,0 +1,12 @@ + + + + + + Templar Tool + + + + + + \ No newline at end of file diff --git a/wasmApp/src/wasmJsMain/resources/style.css b/wasmApp/src/wasmJsMain/resources/style.css new file mode 100644 index 0000000..0608973 --- /dev/null +++ b/wasmApp/src/wasmJsMain/resources/style.css @@ -0,0 +1,7 @@ +html, body { + width: 100%; + height: 100%; + margin: 0; + padding: 0; + overflow: hidden; +} \ No newline at end of file From 5c214b8a6c7d5e2bc42bc1bbe8ba40f591f02a08 Mon Sep 17 00:00:00 2001 From: Steyn Geldenhuys Date: Fri, 19 Jul 2024 07:32:36 +0200 Subject: [PATCH 2/4] Add WasmJs support to the library section and a basic demo app showing functionality. --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 64dcd73..61080de 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -1,5 +1,5 @@ [versions] -agp = "8.2.0" +agp = "8.4.2" dokka = "1.9.10" nexusPlugin = "0.29.0" kotlin = "2.0.0" From 99938bfe4b01ad88b3e35355daffe572d0ec86ab Mon Sep 17 00:00:00 2001 From: Steyn Geldenhuys Date: Fri, 19 Jul 2024 07:38:54 +0200 Subject: [PATCH 3/4] Code formatting according to Spotless --- wasmApp/src/commonMain/kotlin/PickColour.kt | 48 +++++++++++++++++---- wasmApp/src/wasmJsMain/kotlin/Main.kt | 15 +++++++ 2 files changed, 54 insertions(+), 9 deletions(-) diff --git a/wasmApp/src/commonMain/kotlin/PickColour.kt b/wasmApp/src/commonMain/kotlin/PickColour.kt index bc61f3e..edfe740 100644 --- a/wasmApp/src/commonMain/kotlin/PickColour.kt +++ b/wasmApp/src/commonMain/kotlin/PickColour.kt @@ -1,15 +1,45 @@ +/* + * Designed and developed by 2022 skydoves (Jaewoong Eum) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ import androidx.compose.foundation.background -import androidx.compose.foundation.layout.* +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size +import androidx.compose.foundation.layout.width import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.foundation.text.selection.SelectionContainer import androidx.compose.material.Text -import androidx.compose.runtime.* +import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip import androidx.compose.ui.graphics.Color import androidx.compose.ui.unit.dp -import com.github.skydoves.colorpicker.compose.* +import com.github.skydoves.colorpicker.compose.AlphaSlider +import com.github.skydoves.colorpicker.compose.AlphaTile +import com.github.skydoves.colorpicker.compose.BrightnessSlider +import com.github.skydoves.colorpicker.compose.ColorEnvelope +import com.github.skydoves.colorpicker.compose.HsvColorPicker +import com.github.skydoves.colorpicker.compose.rememberColorPickerController @Composable fun PickColour() { @@ -19,14 +49,14 @@ fun PickColour() { ColorEnvelope( Color.Green, "ff00ff00", - false - ) + false, + ), ) } Column( modifier = Modifier.fillMaxSize().background(Color.Black), - horizontalAlignment = Alignment.CenterHorizontally + horizontalAlignment = Alignment.CenterHorizontally, ) { HsvColorPicker( initialColor = currentColorEnvelope.color, @@ -34,7 +64,7 @@ fun PickColour() { controller = controller, onColorChanged = { colorEnvelope: ColorEnvelope -> currentColorEnvelope = colorEnvelope - } + }, ) Spacer(Modifier.height(8.dp)) @@ -60,7 +90,7 @@ fun PickColour() { SelectionContainer { Text( currentColorEnvelope.hexCode, - color = currentColorEnvelope.color + color = currentColorEnvelope.color, ) } @@ -68,7 +98,7 @@ fun PickColour() { modifier = Modifier .size(80.dp) .clip(RoundedCornerShape(6.dp)), - controller = controller + controller = controller, ) } } diff --git a/wasmApp/src/wasmJsMain/kotlin/Main.kt b/wasmApp/src/wasmJsMain/kotlin/Main.kt index d88f689..f283d4a 100644 --- a/wasmApp/src/wasmJsMain/kotlin/Main.kt +++ b/wasmApp/src/wasmJsMain/kotlin/Main.kt @@ -1,3 +1,18 @@ +/* + * Designed and developed by 2022 skydoves (Jaewoong Eum) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ import androidx.compose.ui.ExperimentalComposeUiApi import androidx.compose.ui.window.ComposeViewport import kotlinx.browser.document From 43f44a44857805f16f9cab0d73825d844eef4185 Mon Sep 17 00:00:00 2001 From: Steyn Geldenhuys Date: Fri, 19 Jul 2024 07:57:31 +0200 Subject: [PATCH 4/4] Change page title to something that makes more sense. --- wasmApp/src/wasmJsMain/resources/index.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wasmApp/src/wasmJsMain/resources/index.html b/wasmApp/src/wasmJsMain/resources/index.html index 68da9ee..b574d51 100644 --- a/wasmApp/src/wasmJsMain/resources/index.html +++ b/wasmApp/src/wasmJsMain/resources/index.html @@ -3,7 +3,7 @@ - Templar Tool + WasmJs Color Picker