diff --git a/ci/compose-uber-jar/gradle.properties b/ci/compose-uber-jar/gradle.properties index ab20c3b1b4c..38875d51ea6 100644 --- a/ci/compose-uber-jar/gradle.properties +++ b/ci/compose-uber-jar/gradle.properties @@ -1,2 +1,2 @@ -compose.version=1.5.11 +compose.version=1.6.0 kotlin.code.style=official diff --git a/ci/templates/desktop-template/gradle.properties b/ci/templates/desktop-template/gradle.properties index cb7bbd86bc8..98aed13c99c 100644 --- a/ci/templates/desktop-template/gradle.properties +++ b/ci/templates/desktop-template/gradle.properties @@ -1,4 +1,4 @@ org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8 kotlin.code.style=official -kotlin.version=1.9.21 -compose.version=1.5.11 +kotlin.version=1.9.22 +compose.version=1.6.0 diff --git a/ci/templates/html-library-template/gradle.properties b/ci/templates/html-library-template/gradle.properties index cb7bbd86bc8..98aed13c99c 100644 --- a/ci/templates/html-library-template/gradle.properties +++ b/ci/templates/html-library-template/gradle.properties @@ -1,4 +1,4 @@ org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8 kotlin.code.style=official -kotlin.version=1.9.21 -compose.version=1.5.11 +kotlin.version=1.9.22 +compose.version=1.6.0 diff --git a/ci/templates/multiplatform-template/gradle.properties b/ci/templates/multiplatform-template/gradle.properties index 75b8747f918..1672037284e 100644 --- a/ci/templates/multiplatform-template/gradle.properties +++ b/ci/templates/multiplatform-template/gradle.properties @@ -2,6 +2,6 @@ org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8 android.useAndroidX=true android.enableJetifier=true kotlin.code.style=official -kotlin.version=1.9.21 +kotlin.version=1.9.22 agp.version=8.0.2 -compose.version=1.5.11 +compose.version=1.6.0 diff --git a/examples/chat/gradle.properties b/examples/chat/gradle.properties index 39193936c1f..f4ce9a785c1 100644 --- a/examples/chat/gradle.properties +++ b/examples/chat/gradle.properties @@ -8,6 +8,6 @@ kotlin.native.useEmbeddableCompilerJar=true kotlin.mpp.androidSourceSetLayoutVersion=2 # Enable kotlin/native experimental memory model kotlin.native.binary.memoryModel=experimental -kotlin.version=1.9.21 +kotlin.version=1.9.22 agp.version=8.0.2 -compose.version=1.5.11 +compose.version=1.6.0 diff --git a/examples/cocoapods-ios-example/gradle.properties b/examples/cocoapods-ios-example/gradle.properties index 4e4d26edf7a..666109effa1 100644 --- a/examples/cocoapods-ios-example/gradle.properties +++ b/examples/cocoapods-ios-example/gradle.properties @@ -18,6 +18,6 @@ android.minSdk=24 #Compose #Versions -kotlin.version=1.9.21 +kotlin.version=1.9.22 agp.version=8.0.2 -compose.version=1.5.11 \ No newline at end of file +compose.version=1.6.0 \ No newline at end of file diff --git a/examples/codeviewer/gradle.properties b/examples/codeviewer/gradle.properties index 39193936c1f..f4ce9a785c1 100644 --- a/examples/codeviewer/gradle.properties +++ b/examples/codeviewer/gradle.properties @@ -8,6 +8,6 @@ kotlin.native.useEmbeddableCompilerJar=true kotlin.mpp.androidSourceSetLayoutVersion=2 # Enable kotlin/native experimental memory model kotlin.native.binary.memoryModel=experimental -kotlin.version=1.9.21 +kotlin.version=1.9.22 agp.version=8.0.2 -compose.version=1.5.11 +compose.version=1.6.0 diff --git a/examples/graphics-2d/gradle.properties b/examples/graphics-2d/gradle.properties index 03b0eabdfe6..c444bd01b8a 100644 --- a/examples/graphics-2d/gradle.properties +++ b/examples/graphics-2d/gradle.properties @@ -8,9 +8,9 @@ kotlin.native.useEmbeddableCompilerJar=true kotlin.mpp.androidSourceSetLayoutVersion=2 # Enable kotlin/native experimental memory model kotlin.native.binary.memoryModel=experimental -kotlin.version=1.9.21 +kotlin.version=1.9.22 agp.version=8.0.2 -compose.version=1.5.11 +compose.version=1.6.0 # TODO: remove when switching to 1.9.10. See: https://youtrack.jetbrains.com/issue/KT-60852 # usage: ./gradlew :jsApp:jsBrowserRun -Pworkaround.kotlin.js.kt60852=true diff --git a/examples/html/compose-bird/gradle.properties b/examples/html/compose-bird/gradle.properties index a6a74725e76..b61a2e5972f 100644 --- a/examples/html/compose-bird/gradle.properties +++ b/examples/html/compose-bird/gradle.properties @@ -1,3 +1,3 @@ kotlin.code.style=official -kotlin.version=1.9.21 -compose.version=1.5.11 +kotlin.version=1.9.22 +compose.version=1.6.0 diff --git a/examples/html/compose-in-js/gradle.properties b/examples/html/compose-in-js/gradle.properties index a05fda4a7de..7cb358ab312 100644 --- a/examples/html/compose-in-js/gradle.properties +++ b/examples/html/compose-in-js/gradle.properties @@ -1,4 +1,4 @@ kotlin.code.style=official kotlin.js.webpack.major.version=4 -kotlin.version=1.9.21 -compose.version=1.5.11 +kotlin.version=1.9.22 +compose.version=1.6.0 diff --git a/examples/html/landing/gradle.properties b/examples/html/landing/gradle.properties index a6a74725e76..b61a2e5972f 100644 --- a/examples/html/landing/gradle.properties +++ b/examples/html/landing/gradle.properties @@ -1,3 +1,3 @@ kotlin.code.style=official -kotlin.version=1.9.21 -compose.version=1.5.11 +kotlin.version=1.9.22 +compose.version=1.6.0 diff --git a/examples/html/with-react/gradle.properties b/examples/html/with-react/gradle.properties index a6a74725e76..b61a2e5972f 100644 --- a/examples/html/with-react/gradle.properties +++ b/examples/html/with-react/gradle.properties @@ -1,3 +1,3 @@ kotlin.code.style=official -kotlin.version=1.9.21 -compose.version=1.5.11 +kotlin.version=1.9.22 +compose.version=1.6.0 diff --git a/examples/imageviewer/gradle.properties b/examples/imageviewer/gradle.properties index 4491ab8979f..ca5d42305c2 100644 --- a/examples/imageviewer/gradle.properties +++ b/examples/imageviewer/gradle.properties @@ -8,6 +8,6 @@ kotlin.mpp.androidSourceSetLayoutVersion=2 kotlin.native.useEmbeddableCompilerJar=true # Enable kotlin/native experimental memory model kotlin.native.binary.memoryModel=experimental -kotlin.version=1.9.21 +kotlin.version=1.9.22 agp.version=8.0.2 -compose.version=1.5.11 +compose.version=1.6.0 diff --git a/examples/intellij-plugin/gradle.properties b/examples/intellij-plugin/gradle.properties index a6a74725e76..b61a2e5972f 100644 --- a/examples/intellij-plugin/gradle.properties +++ b/examples/intellij-plugin/gradle.properties @@ -1,3 +1,3 @@ kotlin.code.style=official -kotlin.version=1.9.21 -compose.version=1.5.11 +kotlin.version=1.9.22 +compose.version=1.6.0 diff --git a/examples/interop/ios-compose-in-swiftui/gradle.properties b/examples/interop/ios-compose-in-swiftui/gradle.properties index fc35ea74954..4f122f8b6e0 100644 --- a/examples/interop/ios-compose-in-swiftui/gradle.properties +++ b/examples/interop/ios-compose-in-swiftui/gradle.properties @@ -1,5 +1,5 @@ kotlin.code.style=official xcodeproj=./iosApp org.gradle.jvmargs=-Xmx3g -kotlin.version=1.9.21 -compose.version=1.5.11 +kotlin.version=1.9.22 +compose.version=1.6.0 diff --git a/examples/interop/ios-compose-in-uikit/gradle.properties b/examples/interop/ios-compose-in-uikit/gradle.properties index 9709e7baad9..e0ebafa9970 100644 --- a/examples/interop/ios-compose-in-uikit/gradle.properties +++ b/examples/interop/ios-compose-in-uikit/gradle.properties @@ -3,5 +3,5 @@ xcodeproj=./iosApp org.gradle.jvmargs=-Xmx3g # Enable kotlin/native experimental memory model kotlin.native.binary.memoryModel=experimental -kotlin.version=1.9.21 -compose.version=1.5.11 +kotlin.version=1.9.22 +compose.version=1.6.0 diff --git a/examples/interop/ios-swiftui-in-compose/gradle.properties b/examples/interop/ios-swiftui-in-compose/gradle.properties index 9709e7baad9..e0ebafa9970 100644 --- a/examples/interop/ios-swiftui-in-compose/gradle.properties +++ b/examples/interop/ios-swiftui-in-compose/gradle.properties @@ -3,5 +3,5 @@ xcodeproj=./iosApp org.gradle.jvmargs=-Xmx3g # Enable kotlin/native experimental memory model kotlin.native.binary.memoryModel=experimental -kotlin.version=1.9.21 -compose.version=1.5.11 +kotlin.version=1.9.22 +compose.version=1.6.0 diff --git a/examples/interop/ios-swiftui-in-compose/iosApp/iosApp/ComposeViewControllerRepresentable.swift b/examples/interop/ios-swiftui-in-compose/iosApp/iosApp/ComposeViewControllerRepresentable.swift index 05ec00cba7f..0c02a6a54e9 100644 --- a/examples/interop/ios-swiftui-in-compose/iosApp/iosApp/ComposeViewControllerRepresentable.swift +++ b/examples/interop/ios-swiftui-in-compose/iosApp/iosApp/ComposeViewControllerRepresentable.swift @@ -5,35 +5,14 @@ import MapKit struct ComposeViewControllerRepresentable: UIViewControllerRepresentable { func makeUIViewController(context: Context) -> UIViewController { - return Main_iosKt.ComposeEntryPointWithUIView(createUIView: { () -> UIView in - SwiftUIInUIView( - content: VStack { - Text("SwiftUI in Compose Multiplatform") - } - ) + return Main_iosKt.ComposeEntryPointWithUIViewController(createUIViewController: { () -> UIViewController in + let swiftUIView = VStack { + Text("SwiftUI in Compose Multiplatform") + } + return UIHostingController(rootView: swiftUIView) }) } func updateUIViewController(_ uiViewController: UIViewController, context: Context) { } } - -private class SwiftUIInUIView: UIView { - - init(content: Content) { - super.init(frame: CGRect()) - let hostingController = UIHostingController(rootView: content) - hostingController.view.translatesAutoresizingMaskIntoConstraints = false - addSubview(hostingController.view) - NSLayoutConstraint.activate([ - hostingController.view.topAnchor.constraint(equalTo: topAnchor), - hostingController.view.leadingAnchor.constraint(equalTo: leadingAnchor), - hostingController.view.trailingAnchor.constraint(equalTo: trailingAnchor), - hostingController.view.bottomAnchor.constraint(equalTo: bottomAnchor) - ]) - } - - required init?(coder: NSCoder) { - fatalError("init(coder:) has not been implemented") - } -} diff --git a/examples/interop/ios-swiftui-in-compose/shared/src/iosMain/kotlin/main.ios.kt b/examples/interop/ios-swiftui-in-compose/shared/src/iosMain/kotlin/main.ios.kt index 7486a6ec345..7af0d60047c 100644 --- a/examples/interop/ios-swiftui-in-compose/shared/src/iosMain/kotlin/main.ios.kt +++ b/examples/interop/ios-swiftui-in-compose/shared/src/iosMain/kotlin/main.ios.kt @@ -5,6 +5,7 @@ import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color import androidx.compose.ui.interop.UIKitView +import androidx.compose.ui.interop.UIKitViewController import androidx.compose.ui.unit.dp import androidx.compose.ui.window.ComposeUIViewController import kotlinx.cinterop.ExperimentalForeignApi @@ -12,7 +13,9 @@ import platform.UIKit.UIView import platform.UIKit.UIViewController @OptIn(ExperimentalForeignApi::class) -fun ComposeEntryPointWithUIView(createUIView: () -> UIView): UIViewController = +fun ComposeEntryPointWithUIViewController( + createUIViewController: () -> UIViewController +): UIViewController = ComposeUIViewController { Column( Modifier @@ -21,8 +24,8 @@ fun ComposeEntryPointWithUIView(createUIView: () -> UIView): UIViewController = horizontalAlignment = Alignment.CenterHorizontally ) { Text("How to use SwiftUI inside Compose Multiplatform") - UIKitView( - factory = createUIView, + UIKitViewController( + factory = createUIViewController, modifier = Modifier.size(300.dp).border(2.dp, Color.Blue), ) } diff --git a/examples/interop/ios-uikit-in-compose/gradle.properties b/examples/interop/ios-uikit-in-compose/gradle.properties index 9709e7baad9..e0ebafa9970 100644 --- a/examples/interop/ios-uikit-in-compose/gradle.properties +++ b/examples/interop/ios-uikit-in-compose/gradle.properties @@ -3,5 +3,5 @@ xcodeproj=./iosApp org.gradle.jvmargs=-Xmx3g # Enable kotlin/native experimental memory model kotlin.native.binary.memoryModel=experimental -kotlin.version=1.9.21 -compose.version=1.5.11 +kotlin.version=1.9.22 +compose.version=1.6.0 diff --git a/examples/issues/gradle.properties b/examples/issues/gradle.properties index 28b557bff09..d4a549a70bc 100644 --- a/examples/issues/gradle.properties +++ b/examples/issues/gradle.properties @@ -19,6 +19,6 @@ kotlin.code.style=official android.useAndroidX=true # Automatically convert third-party libraries to use AndroidX android.enableJetifier=true -kotlin.version=1.9.21 +kotlin.version=1.9.22 agp.version=8.0.2 -compose.version=1.5.11 +compose.version=1.6.0 diff --git a/examples/notepad/gradle.properties b/examples/notepad/gradle.properties index cb7bbd86bc8..98aed13c99c 100644 --- a/examples/notepad/gradle.properties +++ b/examples/notepad/gradle.properties @@ -1,4 +1,4 @@ org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8 kotlin.code.style=official -kotlin.version=1.9.21 -compose.version=1.5.11 +kotlin.version=1.9.22 +compose.version=1.6.0 diff --git a/examples/todoapp-lite/gradle.properties b/examples/todoapp-lite/gradle.properties index 39193936c1f..f4ce9a785c1 100755 --- a/examples/todoapp-lite/gradle.properties +++ b/examples/todoapp-lite/gradle.properties @@ -8,6 +8,6 @@ kotlin.native.useEmbeddableCompilerJar=true kotlin.mpp.androidSourceSetLayoutVersion=2 # Enable kotlin/native experimental memory model kotlin.native.binary.memoryModel=experimental -kotlin.version=1.9.21 +kotlin.version=1.9.22 agp.version=8.0.2 -compose.version=1.5.11 +compose.version=1.6.0 diff --git a/examples/widgets-gallery/gradle.properties b/examples/widgets-gallery/gradle.properties index 39193936c1f..96596e8d809 100644 --- a/examples/widgets-gallery/gradle.properties +++ b/examples/widgets-gallery/gradle.properties @@ -8,6 +8,7 @@ kotlin.native.useEmbeddableCompilerJar=true kotlin.mpp.androidSourceSetLayoutVersion=2 # Enable kotlin/native experimental memory model kotlin.native.binary.memoryModel=experimental -kotlin.version=1.9.21 +kotlin.version=1.9.22 agp.version=8.0.2 -compose.version=1.5.11 +# Replace this with release version when it comes out +compose.version=1.6.0 diff --git a/examples/widgets-gallery/shared/build.gradle.kts b/examples/widgets-gallery/shared/build.gradle.kts index 26fd7599d3f..fadb5ec3a70 100644 --- a/examples/widgets-gallery/shared/build.gradle.kts +++ b/examples/widgets-gallery/shared/build.gradle.kts @@ -1,4 +1,5 @@ -@file:Suppress("OPT_IN_IS_NOT_ENABLED") +import org.jetbrains.kotlin.gradle.ExperimentalKotlinGradlePluginApi +import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSetTree plugins { kotlin("multiplatform") @@ -9,7 +10,19 @@ plugins { version = "1.0-SNAPSHOT" kotlin { - androidTarget() + androidTarget { + @OptIn(ExperimentalKotlinGradlePluginApi::class) + instrumentedTestVariant { + sourceSetTree.set(KotlinSourceSetTree.test) + + dependencies { + // Remove the dependency on ui-test-junit4-android when 1.7.0 is released, + // as the needed classes in will have moved to ui-test + implementation("androidx.compose.ui:ui-test-junit4-android:1.6.0") + debugImplementation("androidx.compose.ui:ui-test-manifest") + } + } + } jvm("desktop") @@ -32,33 +45,34 @@ kotlin { implementation(compose.material) implementation(compose.materialIconsExtended) @OptIn(org.jetbrains.compose.ExperimentalComposeLibrary::class) - implementation("org.jetbrains.compose.components:components-resources:1.6.0-dev1306") + implementation("org.jetbrains.compose.components:components-resources:${project.property("compose.version")}") } } val androidMain by getting { dependencies { - api("androidx.activity:activity-compose:1.7.2") + api("androidx.activity:activity-compose:1.8.2") api("androidx.appcompat:appcompat:1.6.1") - api("androidx.core:core-ktx:1.10.1") + api("androidx.core:core-ktx:1.12.0") } } - val iosMain by creating { - dependsOn(commonMain) - } - val iosX64Main by getting { - dependsOn(iosMain) - } - val iosArm64Main by getting { - dependsOn(iosMain) - } - val iosSimulatorArm64Main by getting { - dependsOn(iosMain) - } val desktopMain by getting { dependencies { implementation(compose.desktop.common) } } + val desktopTest by getting { + dependencies { + implementation(compose.desktop.currentOs) + } + } + val commonTest by getting { + dependencies { + implementation(kotlin("test")) + + @OptIn(org.jetbrains.compose.ExperimentalComposeLibrary::class) + implementation(compose.uiTest) + } + } } } @@ -71,6 +85,7 @@ android { defaultConfig { minSdk = 26 + testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" } compileOptions { sourceCompatibility = JavaVersion.VERSION_17 diff --git a/examples/widgets-gallery/shared/src/commonMain/resources/composeRes/images/ic_instagram.xml b/examples/widgets-gallery/shared/src/commonMain/composeResources/drawable/ic_instagram.xml similarity index 100% rename from examples/widgets-gallery/shared/src/commonMain/resources/composeRes/images/ic_instagram.xml rename to examples/widgets-gallery/shared/src/commonMain/composeResources/drawable/ic_instagram.xml diff --git a/examples/widgets-gallery/shared/src/commonMain/resources/composeRes/images/ic_send.xml b/examples/widgets-gallery/shared/src/commonMain/composeResources/drawable/ic_send.xml similarity index 100% rename from examples/widgets-gallery/shared/src/commonMain/resources/composeRes/images/ic_send.xml rename to examples/widgets-gallery/shared/src/commonMain/composeResources/drawable/ic_send.xml diff --git a/examples/widgets-gallery/shared/src/commonMain/resources/composeRes/images/ic_twitter.xml b/examples/widgets-gallery/shared/src/commonMain/composeResources/drawable/ic_twitter.xml similarity index 100% rename from examples/widgets-gallery/shared/src/commonMain/resources/composeRes/images/ic_twitter.xml rename to examples/widgets-gallery/shared/src/commonMain/composeResources/drawable/ic_twitter.xml diff --git a/examples/widgets-gallery/shared/src/commonMain/resources/composeRes/images/p1.jpeg b/examples/widgets-gallery/shared/src/commonMain/composeResources/drawable/p1.jpeg similarity index 100% rename from examples/widgets-gallery/shared/src/commonMain/resources/composeRes/images/p1.jpeg rename to examples/widgets-gallery/shared/src/commonMain/composeResources/drawable/p1.jpeg diff --git a/examples/widgets-gallery/shared/src/commonMain/resources/composeRes/images/p2.jpeg b/examples/widgets-gallery/shared/src/commonMain/composeResources/drawable/p2.jpeg similarity index 100% rename from examples/widgets-gallery/shared/src/commonMain/resources/composeRes/images/p2.jpeg rename to examples/widgets-gallery/shared/src/commonMain/composeResources/drawable/p2.jpeg diff --git a/examples/widgets-gallery/shared/src/commonMain/resources/composeRes/images/p3.jpeg b/examples/widgets-gallery/shared/src/commonMain/composeResources/drawable/p3.jpeg similarity index 100% rename from examples/widgets-gallery/shared/src/commonMain/resources/composeRes/images/p3.jpeg rename to examples/widgets-gallery/shared/src/commonMain/composeResources/drawable/p3.jpeg diff --git a/examples/widgets-gallery/shared/src/commonMain/resources/composeRes/images/p6.jpeg b/examples/widgets-gallery/shared/src/commonMain/composeResources/drawable/p6.jpeg similarity index 100% rename from examples/widgets-gallery/shared/src/commonMain/resources/composeRes/images/p6.jpeg rename to examples/widgets-gallery/shared/src/commonMain/composeResources/drawable/p6.jpeg diff --git a/examples/widgets-gallery/shared/src/commonMain/resources/composeRes/values/strings.xml b/examples/widgets-gallery/shared/src/commonMain/composeResources/values/strings.xml similarity index 100% rename from examples/widgets-gallery/shared/src/commonMain/resources/composeRes/values/strings.xml rename to examples/widgets-gallery/shared/src/commonMain/composeResources/values/strings.xml diff --git a/examples/widgets-gallery/shared/src/commonMain/kotlin/org/jetbrains/compose/demo/widgets/platform/Res.kt b/examples/widgets-gallery/shared/src/commonMain/kotlin/org/jetbrains/compose/demo/widgets/platform/Res.kt deleted file mode 100644 index cfa63a89659..00000000000 --- a/examples/widgets-gallery/shared/src/commonMain/kotlin/org/jetbrains/compose/demo/widgets/platform/Res.kt +++ /dev/null @@ -1,9 +0,0 @@ -package org.jetbrains.compose.demo.widgets.platform - -object Res { - object strings { - val spotify_nav_home = "Home" - val spotify_nav_search = "Search" - val spotify_nav_library = "Your Library" - } -} \ No newline at end of file diff --git a/examples/widgets-gallery/shared/src/commonMain/kotlin/org/jetbrains/compose/demo/widgets/ui/MainView.kt b/examples/widgets-gallery/shared/src/commonMain/kotlin/org/jetbrains/compose/demo/widgets/ui/MainView.kt index a398a61b4c6..e008688db93 100644 --- a/examples/widgets-gallery/shared/src/commonMain/kotlin/org/jetbrains/compose/demo/widgets/ui/MainView.kt +++ b/examples/widgets-gallery/shared/src/commonMain/kotlin/org/jetbrains/compose/demo/widgets/ui/MainView.kt @@ -20,6 +20,7 @@ import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clipToBounds import androidx.compose.ui.platform.LocalDensity +import androidx.compose.ui.platform.testTag import androidx.compose.ui.semantics.Role import androidx.compose.ui.semantics.SemanticsProperties import androidx.compose.ui.semantics.semantics @@ -115,6 +116,10 @@ private fun WidgetsListView(widgetsTypeState: MutableState) { } +val WidgetsType.listItemTestTag: String + get() = "${testTag}_list_item" + + @Composable private fun WidgetsListItemViewImpl( widgetsType: WidgetsType, @@ -133,6 +138,7 @@ private fun WidgetsListItemViewImpl( } .height(height) .padding(start = 16.dp) + .testTag(widgetsType.listItemTestTag) ) { val inFocusInteractionSource = remember { MutableInteractionSource() } val inFocus by inFocusInteractionSource.collectIsHoveredAsState() diff --git a/examples/widgets-gallery/shared/src/commonMain/kotlin/org/jetbrains/compose/demo/widgets/ui/WidgetView.kt b/examples/widgets-gallery/shared/src/commonMain/kotlin/org/jetbrains/compose/demo/widgets/ui/WidgetView.kt index 07468259f5c..757552d48b1 100644 --- a/examples/widgets-gallery/shared/src/commonMain/kotlin/org/jetbrains/compose/demo/widgets/ui/WidgetView.kt +++ b/examples/widgets-gallery/shared/src/commonMain/kotlin/org/jetbrains/compose/demo/widgets/ui/WidgetView.kt @@ -2,7 +2,6 @@ package org.jetbrains.compose.demo.widgets.ui import androidx.compose.foundation.gestures.detectTapGestures import androidx.compose.foundation.layout.Box -import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.verticalScroll @@ -19,7 +18,7 @@ fun WidgetsView( modifier: Modifier ) { ClearFocusBox { - Column(modifier = modifier.verticalScroll(state = rememberScrollState())) { + Box(modifier = modifier.verticalScroll(state = rememberScrollState())) { @Suppress("UNUSED_VARIABLE") val exhaustive = when (widgetsTypeState.value) { WidgetsType.APP_BARS -> AppBars() diff --git a/examples/widgets-gallery/shared/src/commonMain/kotlin/org/jetbrains/compose/demo/widgets/ui/WidgetsType.kt b/examples/widgets-gallery/shared/src/commonMain/kotlin/org/jetbrains/compose/demo/widgets/ui/WidgetsType.kt index 80b03c7655e..59d1d1e60d6 100644 --- a/examples/widgets-gallery/shared/src/commonMain/kotlin/org/jetbrains/compose/demo/widgets/ui/WidgetsType.kt +++ b/examples/widgets-gallery/shared/src/commonMain/kotlin/org/jetbrains/compose/demo/widgets/ui/WidgetsType.kt @@ -24,9 +24,12 @@ enum class WidgetsType(private val customTitle: String? = null) { val title: String get() = customTitle ?: readableName + val testTag: String + get() = name.lowercase() + companion object { val sortedValues: List by lazy { - values().sortedBy { it.name } + entries.sortedBy { it.name } } } } \ No newline at end of file diff --git a/examples/widgets-gallery/shared/src/commonMain/kotlin/org/jetbrains/compose/demo/widgets/ui/screens/AppBars.kt b/examples/widgets-gallery/shared/src/commonMain/kotlin/org/jetbrains/compose/demo/widgets/ui/screens/AppBars.kt index 49902850787..350b0cb3454 100644 --- a/examples/widgets-gallery/shared/src/commonMain/kotlin/org/jetbrains/compose/demo/widgets/ui/screens/AppBars.kt +++ b/examples/widgets-gallery/shared/src/commonMain/kotlin/org/jetbrains/compose/demo/widgets/ui/screens/AppBars.kt @@ -5,7 +5,8 @@ import androidx.compose.foundation.layout.* import androidx.compose.foundation.shape.CircleShape import androidx.compose.material.* import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.filled.ArrowBack +import androidx.compose.material.icons.automirrored.filled.ArrowBack +import androidx.compose.material.icons.automirrored.outlined.ReadMore import androidx.compose.material.icons.filled.MoreHoriz import androidx.compose.material.icons.filled.StarBorder import androidx.compose.material.icons.outlined.* @@ -14,20 +15,24 @@ import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip +import androidx.compose.ui.platform.testTag import androidx.compose.ui.unit.dp -import org.jetbrains.compose.demo.widgets.platform.Res import org.jetbrains.compose.resources.painterResource import org.jetbrains.compose.demo.widgets.theme.twitterColor +import org.jetbrains.compose.demo.widgets.ui.WidgetsType import org.jetbrains.compose.demo.widgets.ui.utils.SubtitleText import org.jetbrains.compose.demo.widgets.ui.utils.TitleText import org.jetbrains.compose.resources.ExperimentalResourceApi -import org.jetbrains.compose.resources.ImageResource +import org.jetbrains.compose.resources.stringResource +import widgets_gallery.shared.generated.resources.Res @Composable fun AppBars() { - TopAppBarsDemo() - BottomAppBarDemo() - NavigationBarDemo() + Column(Modifier.testTag(WidgetsType.APP_BARS.testTag)) { + TopAppBarsDemo() + BottomAppBarDemo() + NavigationBarDemo() + } } @OptIn(ExperimentalResourceApi::class) @@ -40,7 +45,7 @@ private fun TopAppBarsDemo() { elevation = 8.dp, navigationIcon = { IconButton(onClick = {}) { - Icon(Icons.Default.ArrowBack, contentDescription = "ArrowBack") + Icon(Icons.AutoMirrored.Default.ArrowBack, contentDescription = "ArrowBack") } } ) @@ -54,12 +59,12 @@ private fun TopAppBarsDemo() { elevation = 8.dp, navigationIcon = { IconButton(onClick = {}) { - Icon(painterResource(ImageResource("composeRes/images/ic_instagram.xml")), contentDescription = "Instagram") + Icon(painterResource(Res.drawable.ic_instagram), contentDescription = "Instagram") } }, actions = { IconButton(onClick = {}) { - Icon(painterResource(ImageResource("composeRes/images/ic_send.xml")), contentDescription = "Send") + Icon(painterResource(Res.drawable.ic_send), contentDescription = "Send") } } ) @@ -69,7 +74,7 @@ private fun TopAppBarsDemo() { TopAppBar( title = { Icon( - painterResource(ImageResource("composeRes/images/ic_twitter.xml")), + painterResource(Res.drawable.ic_twitter), contentDescription = "Twitter", tint = twitterColor, modifier = Modifier.fillMaxWidth() @@ -80,7 +85,7 @@ private fun TopAppBarsDemo() { elevation = 8.dp, navigationIcon = { Image( - painterResource(ImageResource("composeRes/images/p6.jpeg")), + painterResource(Res.drawable.p6), contentDescription = "", modifier = Modifier.padding(vertical = 4.dp, horizontal = 8.dp) .requiredSize(32.dp).clip(CircleShape) @@ -100,7 +105,7 @@ private fun TopAppBarsDemo() { @Composable private fun BottomAppBarDemo() { Spacer(modifier = Modifier.height(16.dp)) - SubtitleText("Bottom app bars: Note bottom app bar support FAB cutouts when used with scafolds see demoUI crypto app") + SubtitleText("Bottom app bars: Note bottom app bar support FAB cutouts when used with scaffolds see demoUI crypto app") BottomAppBar( cutoutShape = CircleShape @@ -123,19 +128,19 @@ private fun NavigationBarDemo() { icon = { Icon(Icons.Outlined.Home, contentDescription = "Home") }, selected = navItemState.value == NavType.HOME, onClick = { navItemState.value = NavType.HOME }, - label = { Text(text = Res.strings.spotify_nav_home) }, + label = { Text(text = stringResource(Res.string.spotify_nav_home)) }, ) BottomNavigationItem( icon = { Icon(Icons.Outlined.Search, contentDescription = "Search") }, selected = navItemState.value == NavType.SEARCH, onClick = { navItemState.value = NavType.SEARCH }, - label = { Text(text = Res.strings.spotify_nav_search) } + label = { Text(text = stringResource(Res.string.spotify_nav_search)) } ) BottomNavigationItem( icon = { Icon(Icons.Outlined.LibraryMusic, contentDescription = "LibraryMusic") }, selected = navItemState.value == NavType.LIBRARY, onClick = { navItemState.value = NavType.LIBRARY }, - label = { Text(text = Res.strings.spotify_nav_library) } + label = { Text(text = stringResource(Res.string.spotify_nav_library)) } ) } @@ -143,7 +148,7 @@ private fun NavigationBarDemo() { BottomNavigation { BottomNavigationItem( - icon = { Icon(Icons.Outlined.ReadMore, contentDescription = "ReadMore") }, + icon = { Icon(Icons.AutoMirrored.Outlined.ReadMore, contentDescription = "ReadMore") }, selected = navItemState.value == NavType.HOME, onClick = { navItemState.value = NavType.HOME }, ) diff --git a/examples/widgets-gallery/shared/src/commonMain/kotlin/org/jetbrains/compose/demo/widgets/ui/screens/Buttons.kt b/examples/widgets-gallery/shared/src/commonMain/kotlin/org/jetbrains/compose/demo/widgets/ui/screens/Buttons.kt index a7e5e295b59..7b650d0eee4 100644 --- a/examples/widgets-gallery/shared/src/commonMain/kotlin/org/jetbrains/compose/demo/widgets/ui/screens/Buttons.kt +++ b/examples/widgets-gallery/shared/src/commonMain/kotlin/org/jetbrains/compose/demo/widgets/ui/screens/Buttons.kt @@ -14,14 +14,16 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip import androidx.compose.ui.graphics.Brush import androidx.compose.ui.graphics.Color +import androidx.compose.ui.platform.testTag import androidx.compose.ui.unit.dp import org.jetbrains.compose.demo.widgets.theme.purple import org.jetbrains.compose.demo.widgets.theme.purple200 import org.jetbrains.compose.demo.widgets.theme.typography +import org.jetbrains.compose.demo.widgets.ui.WidgetsType @Composable fun Buttons() { - Column { + Column(Modifier.testTag(WidgetsType.BUTTONS.testTag)) { Button(onClick = {}, modifier = Modifier.padding(8.dp)) { Text(text = "Main Button") } diff --git a/examples/widgets-gallery/shared/src/commonMain/kotlin/org/jetbrains/compose/demo/widgets/ui/screens/Chips.kt b/examples/widgets-gallery/shared/src/commonMain/kotlin/org/jetbrains/compose/demo/widgets/ui/screens/Chips.kt index fa42888f9ad..ce37098f201 100644 --- a/examples/widgets-gallery/shared/src/commonMain/kotlin/org/jetbrains/compose/demo/widgets/ui/screens/Chips.kt +++ b/examples/widgets-gallery/shared/src/commonMain/kotlin/org/jetbrains/compose/demo/widgets/ui/screens/Chips.kt @@ -13,44 +13,62 @@ import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip import androidx.compose.ui.graphics.Color +import androidx.compose.ui.platform.testTag import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.unit.dp +import org.jetbrains.compose.demo.widgets.ui.WidgetsType import org.jetbrains.compose.resources.painterResource import org.jetbrains.compose.demo.widgets.ui.utils.SubtitleText +import org.jetbrains.compose.resources.DrawableResource import org.jetbrains.compose.resources.ExperimentalResourceApi -import org.jetbrains.compose.resources.ImageResource +import widgets_gallery.shared.generated.resources.Res +@OptIn(ExperimentalResourceApi::class) @Composable fun Chips() { - // There is no in-built chips but you can make yours like below - SubtitleText(subtitle = "Custom chips with surface") - Column(modifier = Modifier.padding(8.dp)) { - YoutubeChip(selected = true, text = "Chip", modifier = Modifier.padding(horizontal = 8.dp)) - Spacer(modifier = Modifier.padding(8.dp)) - YoutubeChip( - selected = false, - text = "Inactive", - modifier = Modifier.padding(horizontal = 8.dp) - ) - Spacer(modifier = Modifier.padding(8.dp)) - CustomImageChip(text = "custom", imageId = ImageResource("composeRes/images/p2.jpeg"), selected = true) - Spacer(modifier = Modifier.padding(8.dp)) - CustomImageChip(text = "custom2", imageId = ImageResource("composeRes/images/p6.jpeg"), selected = false) - } - SubtitleText(subtitle = "Buttons with circle clipping.") - Column(modifier = Modifier.padding(8.dp)) { - Button( - onClick = {}, - modifier = Modifier.padding(8.dp).clip(CircleShape) - ) { - Text(text = "Chip button") + Column(Modifier.testTag(WidgetsType.CHIPS.testTag)) { + // There is no in-built chips but you can make yours like below + SubtitleText(subtitle = "Custom chips with surface") + Column(modifier = Modifier.padding(8.dp)) { + YoutubeChip( + selected = true, + text = "Chip", + modifier = Modifier.padding(horizontal = 8.dp) + ) + Spacer(modifier = Modifier.padding(8.dp)) + YoutubeChip( + selected = false, + text = "Inactive", + modifier = Modifier.padding(horizontal = 8.dp) + ) + Spacer(modifier = Modifier.padding(8.dp)) + CustomImageChip( + text = "custom", + imageId = Res.drawable.p2, + selected = true + ) + Spacer(modifier = Modifier.padding(8.dp)) + CustomImageChip( + text = "custom2", + imageId = Res.drawable.p6, + selected = false + ) } - Button( - onClick = {}, - enabled = false, - modifier = Modifier.padding(8.dp).clip(CircleShape) - ) { - Text(text = "Disabled chip") + SubtitleText(subtitle = "Buttons with circle clipping.") + Column(modifier = Modifier.padding(8.dp)) { + Button( + onClick = {}, + modifier = Modifier.padding(8.dp).clip(CircleShape) + ) { + Text(text = "Chip button") + } + Button( + onClick = {}, + enabled = false, + modifier = Modifier.padding(8.dp).clip(CircleShape) + ) { + Text(text = "Disabled chip") + } } } } @@ -62,7 +80,7 @@ fun Chips() { @Composable private fun CustomImageChip( text: String, - imageId: ImageResource, + imageId: DrawableResource, selected: Boolean, modifier: Modifier = Modifier ) { diff --git a/examples/widgets-gallery/shared/src/commonMain/kotlin/org/jetbrains/compose/demo/widgets/ui/screens/Loaders.kt b/examples/widgets-gallery/shared/src/commonMain/kotlin/org/jetbrains/compose/demo/widgets/ui/screens/Loaders.kt index df19865d626..97a6ce4357f 100644 --- a/examples/widgets-gallery/shared/src/commonMain/kotlin/org/jetbrains/compose/demo/widgets/ui/screens/Loaders.kt +++ b/examples/widgets-gallery/shared/src/commonMain/kotlin/org/jetbrains/compose/demo/widgets/ui/screens/Loaders.kt @@ -1,41 +1,34 @@ package org.jetbrains.compose.demo.widgets.ui.screens +import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.Row -import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding import androidx.compose.material.CircularProgressIndicator import androidx.compose.material.LinearProgressIndicator import androidx.compose.material.Text import androidx.compose.runtime.Composable -import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier +import androidx.compose.ui.platform.testTag import androidx.compose.ui.unit.dp +import org.jetbrains.compose.demo.widgets.ui.WidgetsType @Composable fun Loaders() { - AlignedColumn { + Column( + modifier = Modifier + .padding(16.dp) + .testTag(WidgetsType.LOADERS.testTag), + verticalArrangement = Arrangement.spacedBy(16.dp) + ) { CircularProgressIndicator() - } - AlignedColumn { CircularProgressIndicator(strokeWidth = 8.dp) - } - AlignedColumn { LinearProgressIndicator() - } - AlignedColumn { - LinearProgressIndicator() - Text(text = "Loading with text...", modifier = Modifier.padding(8.dp)) + Column { + LinearProgressIndicator() + Text(text = "Loading with text...", modifier = Modifier.padding(8.dp)) + } } } -@Composable -private fun AlignedColumn(content: @Composable () -> Unit) { - Column( - modifier = Modifier.fillMaxWidth().padding(16.dp) - ) { - content() - } -} \ No newline at end of file diff --git a/examples/widgets-gallery/shared/src/commonMain/kotlin/org/jetbrains/compose/demo/widgets/ui/screens/SnackBars.kt b/examples/widgets-gallery/shared/src/commonMain/kotlin/org/jetbrains/compose/demo/widgets/ui/screens/SnackBars.kt index 78946984a7e..ad3af37ea3e 100644 --- a/examples/widgets-gallery/shared/src/commonMain/kotlin/org/jetbrains/compose/demo/widgets/ui/screens/SnackBars.kt +++ b/examples/widgets-gallery/shared/src/commonMain/kotlin/org/jetbrains/compose/demo/widgets/ui/screens/SnackBars.kt @@ -1,38 +1,46 @@ package org.jetbrains.compose.demo.widgets.ui.screens +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.padding import androidx.compose.material.Snackbar import androidx.compose.material.Text import androidx.compose.material.TextButton import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier +import androidx.compose.ui.platform.testTag import androidx.compose.ui.unit.dp -import org.jetbrains.compose.demo.widgets.theme.typography +import org.jetbrains.compose.demo.widgets.ui.WidgetsType @Composable fun SnackBars() { - Snackbar(modifier = Modifier.padding(4.dp)) { - Text(text = "This is a basic snackbar") - } - Snackbar( - modifier = Modifier.padding(4.dp), - action = { - TextButton(onClick = {}) { - Text(text = "Remove") + Column( + modifier = Modifier + .padding(4.dp) + .testTag(WidgetsType.SNACK_BARS.testTag), + verticalArrangement = Arrangement.spacedBy(8.dp) + ) { + Snackbar { + Text(text = "This is a basic snackbar") + } + Snackbar( + action = { + TextButton(onClick = {}) { + Text(text = "Remove") + } } + ) { + Text(text = "This is a basic snackbar with action item") } - ) { - Text(text = "This is a basic Snackbar with action item") - } - Snackbar( - modifier = Modifier.padding(4.dp), - actionOnNewLine = true, - action = { - TextButton(onClick = {}) { - Text(text = "Remove") + Snackbar( + actionOnNewLine = true, + action = { + TextButton(onClick = {}) { + Text(text = "Remove") + } } + ) { + Text(text = "Snackbar with action item below text") } - ) { - Text(text = "Snackbar with action item below text") } } diff --git a/examples/widgets-gallery/shared/src/commonMain/kotlin/org/jetbrains/compose/demo/widgets/ui/screens/TextInputs.kt b/examples/widgets-gallery/shared/src/commonMain/kotlin/org/jetbrains/compose/demo/widgets/ui/screens/TextInputs.kt index b4cc78bd8bf..1df77caf0fa 100644 --- a/examples/widgets-gallery/shared/src/commonMain/kotlin/org/jetbrains/compose/demo/widgets/ui/screens/TextInputs.kt +++ b/examples/widgets-gallery/shared/src/commonMain/kotlin/org/jetbrains/compose/demo/widgets/ui/screens/TextInputs.kt @@ -1,6 +1,7 @@ package org.jetbrains.compose.demo.widgets.ui.screens +import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding import androidx.compose.foundation.text.KeyboardOptions @@ -13,80 +14,84 @@ import androidx.compose.material.icons.filled.Edit import androidx.compose.material.icons.filled.Email import androidx.compose.runtime.* import androidx.compose.ui.Modifier +import androidx.compose.ui.platform.testTag import androidx.compose.ui.text.input.KeyboardType import androidx.compose.ui.text.input.PasswordVisualTransformation import androidx.compose.ui.text.input.TextFieldValue import androidx.compose.ui.unit.dp +import org.jetbrains.compose.demo.widgets.ui.WidgetsType @Composable fun TextInputs() { - var text by remember { mutableStateOf(TextFieldValue("")) } + Column(Modifier.testTag(WidgetsType.TEXT_INPUTS.testTag)) { + var text by remember { mutableStateOf(TextFieldValue("")) } - // TODO Explore CoreTextField + // TODO Explore CoreTextField // CoreTextField( // value = text, // onValueChange = { newValue -> text = newValue }, // modifier = Modifier.padding(8.dp).preferredSize(0.dp), // cursorColor = Color.Magenta // ) - TextField( - value = text, - onValueChange = { newValue -> text = newValue }, - modifier = Modifier.padding(8.dp).fillMaxWidth(), - singleLine = true, - label = { Text("label") }, - placeholder = { Text("placeholder") }, - ) + TextField( + value = text, + onValueChange = { newValue -> text = newValue }, + modifier = Modifier.padding(8.dp).fillMaxWidth(), + singleLine = true, + label = { Text("label") }, + placeholder = { Text("placeholder") }, + ) - OutlinedTextField( - value = text, - modifier = Modifier.padding(8.dp).fillMaxWidth(), - singleLine = true, - label = { Text(text = "Password") }, - placeholder = { Text(text = "12334444") }, - visualTransformation = PasswordVisualTransformation(), - onValueChange = { - text = it - }, - keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Password) - ) + OutlinedTextField( + value = text, + modifier = Modifier.padding(8.dp).fillMaxWidth(), + singleLine = true, + label = { Text(text = "Password") }, + placeholder = { Text(text = "12334444") }, + visualTransformation = PasswordVisualTransformation(), + onValueChange = { + text = it + }, + keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Password) + ) - OutlinedTextField( - value = text, - leadingIcon = { Icon(Icons.Default.Email, contentDescription = "Email") }, - modifier = Modifier.padding(8.dp).fillMaxWidth(), - singleLine = true, - keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Text), - label = { Text(text = "Email address") }, - placeholder = { Text(text = "Your email") }, - onValueChange = { - text = it - } - ) - OutlinedTextField( - value = text, - leadingIcon = { Icon(Icons.Default.Email, contentDescription = "Email") }, - trailingIcon = { Icon(Icons.Default.Edit, contentDescription = "Edit") }, - modifier = Modifier.padding(8.dp).fillMaxWidth(), - singleLine = true, - keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Text), - label = { Text(text = "Email address") }, - placeholder = { Text(text = "Your email") }, - onValueChange = { - text = it - } - ) + OutlinedTextField( + value = text, + leadingIcon = { Icon(Icons.Default.Email, contentDescription = "Email") }, + modifier = Modifier.padding(8.dp).fillMaxWidth(), + singleLine = true, + keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Text), + label = { Text(text = "Email address") }, + placeholder = { Text(text = "Your email") }, + onValueChange = { + text = it + } + ) + OutlinedTextField( + value = text, + leadingIcon = { Icon(Icons.Default.Email, contentDescription = "Email") }, + trailingIcon = { Icon(Icons.Default.Edit, contentDescription = "Edit") }, + modifier = Modifier.padding(8.dp).fillMaxWidth(), + singleLine = true, + keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Text), + label = { Text(text = "Email address") }, + placeholder = { Text(text = "Your email") }, + onValueChange = { + text = it + } + ) - var numberText by remember { mutableStateOf(TextFieldValue("")) } - OutlinedTextField( - value = numberText, - modifier = Modifier.padding(8.dp).fillMaxWidth(), - singleLine = true, - keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number), - label = { Text(text = "Phone number") }, - placeholder = { Text(text = "88888888") }, - onValueChange = { - numberText = it - } - ) + var numberText by remember { mutableStateOf(TextFieldValue("")) } + OutlinedTextField( + value = numberText, + modifier = Modifier.padding(8.dp).fillMaxWidth(), + singleLine = true, + keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number), + label = { Text(text = "Phone number") }, + placeholder = { Text(text = "88888888") }, + onValueChange = { + numberText = it + } + ) + } } diff --git a/examples/widgets-gallery/shared/src/commonMain/kotlin/org/jetbrains/compose/demo/widgets/ui/screens/Texts.kt b/examples/widgets-gallery/shared/src/commonMain/kotlin/org/jetbrains/compose/demo/widgets/ui/screens/Texts.kt index c14f8f95453..d22aca0ba8b 100644 --- a/examples/widgets-gallery/shared/src/commonMain/kotlin/org/jetbrains/compose/demo/widgets/ui/screens/Texts.kt +++ b/examples/widgets-gallery/shared/src/commonMain/kotlin/org/jetbrains/compose/demo/widgets/ui/screens/Texts.kt @@ -1,21 +1,22 @@ package org.jetbrains.compose.demo.widgets.ui.screens import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.padding import androidx.compose.material.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier +import androidx.compose.ui.platform.testTag import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.style.TextDecoration import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.unit.dp import org.jetbrains.compose.demo.widgets.theme.typography +import org.jetbrains.compose.demo.widgets.ui.WidgetsType import org.jetbrains.compose.demo.widgets.ui.utils.SubtitleText @Composable fun TextViews() { - Column { + Column(Modifier.testTag(WidgetsType.TEXT_VIEWS.testTag)) { val textModifier = Modifier.padding(horizontal = 8.dp) SubtitleText(subtitle = "Font weights") diff --git a/examples/widgets-gallery/shared/src/commonMain/kotlin/org/jetbrains/compose/demo/widgets/ui/screens/Toggles.kt b/examples/widgets-gallery/shared/src/commonMain/kotlin/org/jetbrains/compose/demo/widgets/ui/screens/Toggles.kt index ce3ac76ee21..8ed12c84972 100644 --- a/examples/widgets-gallery/shared/src/commonMain/kotlin/org/jetbrains/compose/demo/widgets/ui/screens/Toggles.kt +++ b/examples/widgets-gallery/shared/src/commonMain/kotlin/org/jetbrains/compose/demo/widgets/ui/screens/Toggles.kt @@ -9,11 +9,13 @@ import androidx.compose.material.* import androidx.compose.runtime.* import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier +import androidx.compose.ui.platform.testTag import androidx.compose.ui.unit.dp +import org.jetbrains.compose.demo.widgets.ui.WidgetsType @Composable fun Toggles() { - Column { + Column(Modifier.testTag(WidgetsType.TOGGLES.testTag)) { var checked by remember { mutableStateOf(true) } Checkbox( checked = checked, diff --git a/examples/widgets-gallery/shared/src/commonMain/kotlin/org/jetbrains/compose/demo/widgets/ui/screens/UICards.kt b/examples/widgets-gallery/shared/src/commonMain/kotlin/org/jetbrains/compose/demo/widgets/ui/screens/UICards.kt index 08223f5e6e5..b89579ae136 100644 --- a/examples/widgets-gallery/shared/src/commonMain/kotlin/org/jetbrains/compose/demo/widgets/ui/screens/UICards.kt +++ b/examples/widgets-gallery/shared/src/commonMain/kotlin/org/jetbrains/compose/demo/widgets/ui/screens/UICards.kt @@ -9,96 +9,109 @@ import androidx.compose.material.icons.filled.ShoppingCart import androidx.compose.runtime.Composable import androidx.compose.runtime.remember import androidx.compose.ui.Modifier +import androidx.compose.ui.platform.testTag import androidx.compose.ui.unit.dp import org.jetbrains.compose.demo.widgets.data.DemoDataProvider import org.jetbrains.compose.resources.painterResource import org.jetbrains.compose.demo.widgets.theme.typography +import org.jetbrains.compose.demo.widgets.ui.WidgetsType import org.jetbrains.compose.resources.ExperimentalResourceApi -import org.jetbrains.compose.resources.ImageResource +import widgets_gallery.shared.generated.resources.Res @OptIn(ExperimentalMaterialApi::class, ExperimentalResourceApi::class) @Composable fun UICards() { - val item = remember { DemoDataProvider.item } + Column(Modifier.testTag(WidgetsType.UI_CARDS.testTag)) { + val item = remember { DemoDataProvider.item } - Text( - text = "Inbuilt box as container for any Clipping/Alignment controls", - style = typography.subtitle1, - modifier = Modifier.padding(8.dp) - ) - Card( - modifier = Modifier.padding(8.dp).fillMaxWidth(), - backgroundColor = MaterialTheme.colors.primary, - shape = RoundedCornerShape(topStart = 16.dp, bottomEnd = 16.dp) - ) { - Column { - Text( - text = item.title, - modifier = Modifier.padding(8.dp), - color = MaterialTheme.colors.onPrimary - ) - Text( - text = item.subtitle, - modifier = Modifier.padding(8.dp), - color = MaterialTheme.colors.onPrimary - ) + Text( + text = "Inbuilt box as container for any Clipping/Alignment controls", + style = typography.subtitle1, + modifier = Modifier.padding(8.dp) + ) + Card( + modifier = Modifier.padding(8.dp).fillMaxWidth(), + backgroundColor = MaterialTheme.colors.primary, + shape = RoundedCornerShape(topStart = 16.dp, bottomEnd = 16.dp) + ) { + Column { + Text( + text = item.title, + modifier = Modifier.padding(8.dp), + color = MaterialTheme.colors.onPrimary + ) + Text( + text = item.subtitle, + modifier = Modifier.padding(8.dp), + color = MaterialTheme.colors.onPrimary + ) + } } - } - Divider() + Divider() - Text(text = "Inbuilt Card", style = typography.subtitle1, modifier = Modifier.padding(8.dp)) - Card( - modifier = Modifier.padding(16.dp).fillMaxWidth(), - shape = RoundedCornerShape(4.dp), - elevation = 4.dp - ) { - Row { - Image( - painterResource(ImageResource("composeRes/images/p3.jpeg")), - contentDescription = null, - modifier = Modifier.requiredSize(60.dp) - ) - Text(text = item.title, modifier = Modifier.padding(16.dp)) + Text(text = "Inbuilt Card", style = typography.subtitle1, modifier = Modifier.padding(8.dp)) + Card( + modifier = Modifier.padding(16.dp).fillMaxWidth(), + shape = RoundedCornerShape(4.dp), + elevation = 4.dp + ) { + Row { + Image( + painterResource(Res.drawable.p3), + contentDescription = null, + modifier = Modifier.requiredSize(60.dp) + ) + Text(text = item.title, modifier = Modifier.padding(16.dp)) + } } - } - Divider() + Divider() - Text( - text = "In-built ListItems", - style = typography.subtitle1, - modifier = Modifier.padding(8.dp) - ) - ListItem(text = { Text(item.title) }, secondaryText = { Text(item.subtitle) }) - Divider(modifier = Modifier.padding(4.dp)) - ListItem( - text = { Text(item.title) }, - secondaryText = { Text(item.subtitle) }, - singleLineSecondaryText = false - ) - Divider(modifier = Modifier.padding(4.dp)) - ListItem(text = { Text(item.title) }, secondaryText = { Text(item.subtitle) }, icon = { - Image( - painterResource(ImageResource("composeRes/images/p3.jpeg")), - contentDescription = null + Text( + text = "In-built ListItems", + style = typography.subtitle1, + modifier = Modifier.padding(8.dp) ) - }) - Divider(modifier = Modifier.padding(4.dp)) - //I am not sure why this is not going multiline for secondaryText... - ListItem( - text = { Text(item.title) }, - secondaryText = { Text(item.subtitle) }, - icon = { Image(painterResource(ImageResource("composeRes/images/p1.jpeg")), contentDescription = null) }, - overlineText = { Text("Overline text") }, - singleLineSecondaryText = false - ) - Divider() - ListItem( - text = { Text(item.title) }, - secondaryText = { Text(item.subtitle) }, - icon = { Image(painterResource(ImageResource("composeRes/images/p2.jpeg")), contentDescription = null) }, - trailing = { Icon(Icons.Default.ShoppingCart, contentDescription = null) }, - singleLineSecondaryText = false - ) - Divider() - + ListItem(text = { Text(item.title) }, secondaryText = { Text(item.subtitle) }) + Divider(modifier = Modifier.padding(4.dp)) + ListItem( + text = { Text(item.title) }, + secondaryText = { Text(item.subtitle) }, + singleLineSecondaryText = false + ) + Divider(modifier = Modifier.padding(4.dp)) + ListItem(text = { Text(item.title) }, secondaryText = { Text(item.subtitle) }, icon = { + Image( + painterResource(Res.drawable.p3), + contentDescription = null + ) + }) + Divider(modifier = Modifier.padding(4.dp)) + //I am not sure why this is not going multiline for secondaryText... + ListItem( + text = { Text(item.title) }, + secondaryText = { Text(item.subtitle) }, + icon = { + Image( + painterResource(Res.drawable.p1), + contentDescription = null + ) + }, + overlineText = { Text("Overline text") }, + singleLineSecondaryText = false + ) + Divider() + ListItem( + text = { Text(item.title) }, + secondaryText = { Text(item.subtitle) }, + icon = { + Image( + painterResource(Res.drawable.p2), + contentDescription = null + ) + }, + trailing = { Icon(Icons.Default.ShoppingCart, contentDescription = null) }, + singleLineSecondaryText = false + ) + Divider() + } } \ No newline at end of file diff --git a/examples/widgets-gallery/shared/src/commonMain/kotlin/org/jetbrains/compose/demo/widgets/ui/utils/ResizablePanel.kt b/examples/widgets-gallery/shared/src/commonMain/kotlin/org/jetbrains/compose/demo/widgets/ui/utils/ResizablePanel.kt index 4fe446c26f9..ba4e09306a3 100644 --- a/examples/widgets-gallery/shared/src/commonMain/kotlin/org/jetbrains/compose/demo/widgets/ui/utils/ResizablePanel.kt +++ b/examples/widgets-gallery/shared/src/commonMain/kotlin/org/jetbrains/compose/demo/widgets/ui/utils/ResizablePanel.kt @@ -8,8 +8,8 @@ import androidx.compose.material.Icon import androidx.compose.material.LocalContentColor import androidx.compose.material.Text import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.filled.ArrowBack -import androidx.compose.material.icons.filled.ArrowForward +import androidx.compose.material.icons.automirrored.filled.ArrowBack +import androidx.compose.material.icons.automirrored.filled.ArrowForward import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf @@ -60,7 +60,10 @@ fun ResizablePanel( .clickable { state.isExpanded = !state.isExpanded } ) { Icon( - if (state.isExpanded) Icons.Default.ArrowBack else Icons.Default.ArrowForward, + imageVector = if (state.isExpanded) + Icons.AutoMirrored.Default.ArrowBack + else + Icons.AutoMirrored.Default.ArrowForward, contentDescription = if (state.isExpanded) "Collapse" else "Expand", tint = LocalContentColor.current, modifier = Modifier diff --git a/examples/widgets-gallery/shared/src/commonTest/kotlin/ExampleTest.kt b/examples/widgets-gallery/shared/src/commonTest/kotlin/ExampleTest.kt new file mode 100644 index 00000000000..4c6bf0d9ecd --- /dev/null +++ b/examples/widgets-gallery/shared/src/commonTest/kotlin/ExampleTest.kt @@ -0,0 +1,34 @@ +import androidx.compose.material.* +import androidx.compose.runtime.* +import androidx.compose.ui.Modifier +import androidx.compose.ui.platform.testTag +import androidx.compose.ui.test.* +import kotlin.test.Test + + +/** + * This is a simple, sample test. + */ +class ExampleTest { + @OptIn(ExperimentalTestApi::class) + @Test + fun myTest() = runComposeUiTest { + setContent { + var text by remember { mutableStateOf("Hello") } + Text( + text = text, + modifier = Modifier.testTag("text") + ) + Button( + onClick = { text = "Compose" }, + modifier = Modifier.testTag("button") + ){ + Text("Click me") + } + } + + onNodeWithTag("text").assertTextEquals("Hello") + onNodeWithTag("button").performClick() + onNodeWithTag("text").assertTextEquals("Compose") + } +} \ No newline at end of file diff --git a/examples/widgets-gallery/shared/src/commonTest/kotlin/WidgetsPanelTest.kt b/examples/widgets-gallery/shared/src/commonTest/kotlin/WidgetsPanelTest.kt new file mode 100644 index 00000000000..155b2dd1675 --- /dev/null +++ b/examples/widgets-gallery/shared/src/commonTest/kotlin/WidgetsPanelTest.kt @@ -0,0 +1,28 @@ +import androidx.compose.ui.test.ExperimentalTestApi +import androidx.compose.ui.test.onNodeWithTag +import androidx.compose.ui.test.performClick +import androidx.compose.ui.test.runComposeUiTest +import org.jetbrains.compose.demo.widgets.ui.WidgetsPanel +import org.jetbrains.compose.demo.widgets.ui.WidgetsType +import org.jetbrains.compose.demo.widgets.ui.listItemTestTag +import kotlin.test.Test + + +@OptIn(ExperimentalTestApi::class) +class WidgetsPanelTest { + /** + * Tests that clicking on each widget type in the list shows the corresponding widgets view. + */ + @OptIn(ExperimentalTestApi::class) + @Test + fun clickingOnWidgetListItemShowsCorrectWidgetUi() = runComposeUiTest { + setContent { + WidgetsPanel() + } + + for (widgetsType in WidgetsType.entries) { + onNodeWithTag(widgetsType.listItemTestTag).performClick() + onNodeWithTag(widgetsType.testTag).assertExists() + } + } +} \ No newline at end of file diff --git a/gradle-plugins/gradle.properties b/gradle-plugins/gradle.properties index 81cb376b75a..5e21db2a0a9 100644 --- a/gradle-plugins/gradle.properties +++ b/gradle-plugins/gradle.properties @@ -2,7 +2,7 @@ org.gradle.parallel=true kotlin.code.style=official # Default version of Compose Libraries used by Gradle plugin -compose.version=1.6.0-dev1383 +compose.version=1.6.0 # The latest version of Compose Compiler used by Gradle plugin. Used only in tests/CI. compose.tests.compiler.version=1.5.8.1 # The latest version of Kotlin compatible with compose.tests.compiler.version. Used only in tests/CI. diff --git a/tutorials/HTML/Getting_Started/README.md b/tutorials/HTML/Getting_Started/README.md index 23923d8f449..43487576e8f 100644 --- a/tutorials/HTML/Getting_Started/README.md +++ b/tutorials/HTML/Getting_Started/README.md @@ -36,8 +36,8 @@ pluginManagement { ``` kotlin // Add compose gradle plugin plugins { - kotlin("multiplatform") version "1.9.21" - id("org.jetbrains.compose") version "1.5.11" + kotlin("multiplatform") version "1.9.22" + id("org.jetbrains.compose") version "1.6.0" } // Add maven repositories