From 87b2f8c1f8fe9737a295f1afb6baee45898e4169 Mon Sep 17 00:00:00 2001 From: Shreck Ye Date: Mon, 25 Mar 2024 16:01:51 +0800 Subject: [PATCH 01/75] Initially add `RadioButton` --- README.md | 1 + .../compose/material/RadioButton.kt | 7 +++++ .../compose/material/RadioButton.kt | 8 ++++++ .../compose/material/RadioButton.kt | 10 +++++++ .../huanshankeji/compose/material/demo/App.kt | 26 ++++++++++++++++++- 5 files changed, 51 insertions(+), 1 deletion(-) create mode 100644 compose-multiplatform-material/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material/RadioButton.kt create mode 100644 compose-multiplatform-material/src/commonMain/kotlin/com/huanshankeji/compose/material/RadioButton.kt create mode 100644 compose-multiplatform-material/src/jsMain/kotlin/com/huanshankeji/compose/material/RadioButton.kt diff --git a/README.md b/README.md index e9d4f3d9..b65fe69e 100644 --- a/README.md +++ b/README.md @@ -38,6 +38,7 @@ This project is prototype and there is no documentation yet. Check out [the demo - `Text`/`MaterialText` - `TextField` - `TopAppBarScaffold` +- `RadioButton` ### Styles diff --git a/compose-multiplatform-material/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material/RadioButton.kt b/compose-multiplatform-material/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material/RadioButton.kt new file mode 100644 index 00000000..b12dd313 --- /dev/null +++ b/compose-multiplatform-material/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material/RadioButton.kt @@ -0,0 +1,7 @@ +package com.huanshankeji.compose.material + +import androidx.compose.runtime.Composable + +@Composable +actual fun RadioButton(selected: Boolean, onClick: (() -> Unit)?, enabled: Boolean) = + androidx.compose.material.RadioButton(selected, onClick, enabled = enabled) diff --git a/compose-multiplatform-material/src/commonMain/kotlin/com/huanshankeji/compose/material/RadioButton.kt b/compose-multiplatform-material/src/commonMain/kotlin/com/huanshankeji/compose/material/RadioButton.kt new file mode 100644 index 00000000..08b42869 --- /dev/null +++ b/compose-multiplatform-material/src/commonMain/kotlin/com/huanshankeji/compose/material/RadioButton.kt @@ -0,0 +1,8 @@ +package com.huanshankeji.compose.material + +import androidx.compose.runtime.Composable + +// TODO modifier +// TODO colors +@Composable +expect fun RadioButton(selected: Boolean, onClick: (() -> Unit)?, enabled: Boolean = true) diff --git a/compose-multiplatform-material/src/jsMain/kotlin/com/huanshankeji/compose/material/RadioButton.kt b/compose-multiplatform-material/src/jsMain/kotlin/com/huanshankeji/compose/material/RadioButton.kt new file mode 100644 index 00000000..814c7184 --- /dev/null +++ b/compose-multiplatform-material/src/jsMain/kotlin/com/huanshankeji/compose/material/RadioButton.kt @@ -0,0 +1,10 @@ +package com.huanshankeji.compose.material + +import androidx.compose.runtime.Composable +import dev.petuska.kmdc.radio.MDCRadio + +@Composable +actual fun RadioButton(selected: Boolean, onClick: (() -> Unit)?, enabled: Boolean) = + MDCRadio(selected, disabled = !enabled, attrs = { + if (onClick !== null) onClick { onClick() } + }) diff --git a/demo/src/commonMain/kotlin/com/huanshankeji/compose/material/demo/App.kt b/demo/src/commonMain/kotlin/com/huanshankeji/compose/material/demo/App.kt index 67ece66b..4afbad26 100644 --- a/demo/src/commonMain/kotlin/com/huanshankeji/compose/material/demo/App.kt +++ b/demo/src/commonMain/kotlin/com/huanshankeji/compose/material/demo/App.kt @@ -15,6 +15,10 @@ import com.huanshankeji.compose.ui.height import com.huanshankeji.compose.ui.unit.dpOrPx import com.huanshankeji.compose.ui.width +private enum class RadioButtonState { + A, B, C +} + @OptIn(ConfusableTextApi::class) @Composable fun App() { @@ -29,7 +33,7 @@ fun App() { style { margin(16.dpOrPx) val size = 400.dpOrPx - height(size) + //height(size) width(size) } }) { @@ -112,6 +116,26 @@ fun App() { label = "Demo text field", leadingIcon = { Icon(MaterialIcons.Add, null) }, trailingIcon = { Icon(MaterialIcons.Menu, null) }) + + + var selected by remember { mutableStateOf(RadioButtonState.A) } + // TODO `Modifier.selectableGroup()`, see https://developer.android.com/reference/kotlin/androidx/compose/material/package-summary#RadioButton(kotlin.Boolean,kotlin.Function0,androidx.compose.ui.Modifier,kotlin.Boolean,androidx.compose.foundation.interaction.MutableInteractionSource,androidx.compose.material.RadioButtonColors) + Column { + @Composable + fun RadioButtonRow(state: RadioButtonState) = + // TODO `Modifier.selectable()` + Row { + RadioButton( + selected == state, + { selected = state } // TODO put in the `Row` `modifier` + ) + // TODO put center vertically + Text( + text = state.toString() + ) + } + RadioButtonState.entries.forEach { RadioButtonRow(it) } + } } } } From a778036003f3360486ee12217879587aaa06505f Mon Sep 17 00:00:00 2001 From: Shreck Ye Date: Sun, 14 Apr 2024 19:11:21 +0800 Subject: [PATCH 02/75] Initially set up the Material 3 module and add `Button` composables --- README.md | 4 ++ .../main/kotlin/VersionsAndDependencies.kt | 2 + .../compose/material/Button.js.kt | 23 +++++-- .../compose/material/ext/Button.js.kt | 10 +-- .../build.gradle.kts | 44 ++++++++++++ .../material3/Button.androidxCommon.kt | 16 +++++ .../material3/ext/Button.androidxCommon.kt | 22 ++++++ .../huanshankeji/compose/material3/Button.kt | 26 +++++++ .../compose/material3/ext/Button.kt | 17 +++++ .../compose/html/material3/MdButton.kt | 69 +++++++++++++++++++ .../compose/material3/Button.js.kt | 34 +++++++++ .../compose/material3/ext/Button.js.kt | 24 +++++++ demo/build.gradle.kts | 1 + .../huanshankeji/compose/material/demo/App.kt | 20 ++++-- kotlin-js-store/yarn.lock | 60 ++++++++++++++++ settings.gradle.kts | 1 + 16 files changed, 353 insertions(+), 20 deletions(-) create mode 100644 compose-multiplatform-material3/build.gradle.kts create mode 100644 compose-multiplatform-material3/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material3/Button.androidxCommon.kt create mode 100644 compose-multiplatform-material3/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material3/ext/Button.androidxCommon.kt create mode 100644 compose-multiplatform-material3/src/commonMain/kotlin/com/huanshankeji/compose/material3/Button.kt create mode 100644 compose-multiplatform-material3/src/commonMain/kotlin/com/huanshankeji/compose/material3/ext/Button.kt create mode 100644 compose-multiplatform-material3/src/jsMain/kotlin/com/huanshankeji/compose/html/material3/MdButton.kt create mode 100644 compose-multiplatform-material3/src/jsMain/kotlin/com/huanshankeji/compose/material3/Button.js.kt create mode 100644 compose-multiplatform-material3/src/jsMain/kotlin/com/huanshankeji/compose/material3/ext/Button.js.kt diff --git a/README.md b/README.md index 4e38e401..d98eef0c 100644 --- a/README.md +++ b/README.md @@ -42,6 +42,10 @@ This project is prototype and there is no documentation yet. Check out [the demo - `TextField` - `TopAppBarScaffold` +#### Material 3 components + +- `Button` + #### Components in the `ext` packages The components in the `ext` packages don't follow the `androidx.compose` APIs exactly, but rather provide wrappers are idiomatic and conventional on both kinds of targets, wrapping different APIs which can't be unified following the `androidx.compose` APIs. diff --git a/buildSrc/src/main/kotlin/VersionsAndDependencies.kt b/buildSrc/src/main/kotlin/VersionsAndDependencies.kt index ffe39baa..fc4f1615 100644 --- a/buildSrc/src/main/kotlin/VersionsAndDependencies.kt +++ b/buildSrc/src/main/kotlin/VersionsAndDependencies.kt @@ -9,4 +9,6 @@ object DependencyVersions { val activityCompose = "1.8.2" val compose = "1.6.4" } + + val materialWeb = "1.4.0" } diff --git a/compose-multiplatform-material/src/jsMain/kotlin/com/huanshankeji/compose/material/Button.js.kt b/compose-multiplatform-material/src/jsMain/kotlin/com/huanshankeji/compose/material/Button.js.kt index d624b46c..92b78eb1 100644 --- a/compose-multiplatform-material/src/jsMain/kotlin/com/huanshankeji/compose/material/Button.js.kt +++ b/compose-multiplatform-material/src/jsMain/kotlin/com/huanshankeji/compose/material/Button.js.kt @@ -6,12 +6,26 @@ import com.huanshankeji.compose.foundation.layout.RowScope import com.huanshankeji.compose.material.ext.ButtonType import com.huanshankeji.compose.material.ext.toMDCButtonType import com.huanshankeji.compose.ui.Modifier -import com.huanshankeji.compose.web.attributes.attrs -import com.huanshankeji.compose.web.attributes.plus import com.varabyte.kobweb.compose.ui.toAttrs import dev.petuska.kmdc.button.MDCButton +import dev.petuska.kmdc.button.MDCButtonScope import org.w3c.dom.HTMLButtonElement +@Composable +internal fun CommonButton( + onClick: () -> Unit, + buttonType: ButtonType, + modifier: Modifier, + content: @Composable MDCButtonScope.() -> Unit +) = + MDCButton( + buttonType.toMDCButtonType(), + attrs = modifier.platformModifier.toAttrs { + onClick { onClick() } + }, + content = content + ) + @Composable private fun Button( onClick: () -> Unit, @@ -19,10 +33,7 @@ private fun Button( modifier: Modifier, content: @Composable RowScope.() -> Unit ) = - MDCButton(buttonType.toMDCButtonType(), - attrs = attrs { - onClick { onClick() } - } + modifier.platformModifier.toAttrs()) { + CommonButton(onClick, buttonType, modifier) { Row(content = content) } diff --git a/compose-multiplatform-material/src/jsMain/kotlin/com/huanshankeji/compose/material/ext/Button.js.kt b/compose-multiplatform-material/src/jsMain/kotlin/com/huanshankeji/compose/material/ext/Button.js.kt index 3113a757..b7383876 100644 --- a/compose-multiplatform-material/src/jsMain/kotlin/com/huanshankeji/compose/material/ext/Button.js.kt +++ b/compose-multiplatform-material/src/jsMain/kotlin/com/huanshankeji/compose/material/ext/Button.js.kt @@ -1,13 +1,10 @@ package com.huanshankeji.compose.material.ext import androidx.compose.runtime.Composable +import com.huanshankeji.compose.material.CommonButton import com.huanshankeji.compose.material.ext.ButtonType.* import com.huanshankeji.compose.ui.Modifier -import com.huanshankeji.compose.web.attributes.attrs -import com.huanshankeji.compose.web.attributes.plus -import com.varabyte.kobweb.compose.ui.toAttrs import dev.petuska.kmdc.button.Label -import dev.petuska.kmdc.button.MDCButton import dev.petuska.kmdc.button.MDCButtonScope import dev.petuska.kmdc.button.MDCButtonType import org.w3c.dom.HTMLButtonElement @@ -19,10 +16,7 @@ actual fun Button( modifier: Modifier, content: @Composable ButtonScope.() -> Unit ) = - MDCButton(buttonType.toMDCButtonType(), - attrs = attrs { - onClick { onClick() } - } + modifier.platformModifier.toAttrs()) { + CommonButton(onClick, buttonType, modifier) { ButtonScope(this).content() } diff --git a/compose-multiplatform-material3/build.gradle.kts b/compose-multiplatform-material3/build.gradle.kts new file mode 100644 index 00000000..a102f5df --- /dev/null +++ b/compose-multiplatform-material3/build.gradle.kts @@ -0,0 +1,44 @@ +import com.huanshankeji.team.`Shreck Ye` +import com.huanshankeji.team.pomForTeamDefaultOpenSource + +plugins { + `lib-conventions` +} + +kotlin { + sourceSets { + /* + Use `api`. See: + https://github.com/JetBrains/compose-multiplatform-core/blob/jb-main/compose/material3/material3/build.gradle + https://android.googlesource.com/platform/frameworks/support/+/refs/heads/androidx-main/compose/material3/material3/build.gradle + */ + commonMain { + dependencies { + api(compose.runtime) + api(project(":compose-multiplatform-common")) + //compileOnly(compose.material) // for KDoc element links only + } + } + androidxCommonMain { + dependencies { + api(compose.material3) + } + } + jsMain { + dependencies { + //implementation("com.huanshankeji:compose-web-common:${DependencyVersions.huanshankejiComposeWeb}") // TODO remove + implementation(npm("@material/web", DependencyVersions.materialWeb)) + } + } + } +} + +publishing.publications.withType { + pomForTeamDefaultOpenSource( + project, + "Compose Multiplatform Material 3 wrappers", + "Compose Multiplatform Material Design 3 component wrappers for `androidx.compose` and Compose HTML" + ) { + `Shreck Ye`() + } +} diff --git a/compose-multiplatform-material3/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material3/Button.androidxCommon.kt b/compose-multiplatform-material3/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material3/Button.androidxCommon.kt new file mode 100644 index 00000000..e02c30eb --- /dev/null +++ b/compose-multiplatform-material3/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material3/Button.androidxCommon.kt @@ -0,0 +1,16 @@ +package com.huanshankeji.compose.material3 + +import androidx.compose.runtime.Composable +import com.huanshankeji.compose.foundation.layout.RowScope +import com.huanshankeji.compose.ui.Modifier + +@Composable +actual fun Button( + onClick: () -> Unit, + modifier: Modifier, + enabled: Boolean, + content: @Composable RowScope.() -> Unit +) = + androidx.compose.material3.Button(onClick, modifier.platformModifier, enabled) { + RowScope.Impl(this).content() + } \ No newline at end of file diff --git a/compose-multiplatform-material3/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material3/ext/Button.androidxCommon.kt b/compose-multiplatform-material3/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material3/ext/Button.androidxCommon.kt new file mode 100644 index 00000000..f92617c9 --- /dev/null +++ b/compose-multiplatform-material3/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material3/ext/Button.androidxCommon.kt @@ -0,0 +1,22 @@ +package com.huanshankeji.compose.material3.ext + +import androidx.compose.runtime.Composable +import com.huanshankeji.compose.ui.Modifier + +@Composable +actual fun Button( + onClick: () -> Unit, + modifier: Modifier, + enabled: Boolean, + content: @Composable ButtonScope.() -> Unit +) = + androidx.compose.material3.Button(onClick, modifier.platformModifier, enabled) { + ButtonScope.content() + } + +actual object ButtonScope { + @Composable + actual fun Icon() { + TODO() + } +} diff --git a/compose-multiplatform-material3/src/commonMain/kotlin/com/huanshankeji/compose/material3/Button.kt b/compose-multiplatform-material3/src/commonMain/kotlin/com/huanshankeji/compose/material3/Button.kt new file mode 100644 index 00000000..f53b40b6 --- /dev/null +++ b/compose-multiplatform-material3/src/commonMain/kotlin/com/huanshankeji/compose/material3/Button.kt @@ -0,0 +1,26 @@ +package com.huanshankeji.compose.material3 + +import androidx.compose.runtime.Composable +import com.huanshankeji.compose.foundation.layout.RowScope +import com.huanshankeji.compose.ui.Modifier + +@Composable +expect fun Button( + onClick: () -> Unit, + modifier: Modifier = Modifier, + enabled: Boolean = true, + /* + shape: Shape = ButtonDefaults.shape, + colors: ButtonColors = ButtonDefaults.buttonColors(), + */ + content: @Composable RowScope.() -> Unit +) + +@Composable +fun ElevatedButton( + onClick: () -> Unit, + modifier: Modifier = Modifier, + enabled: Boolean = true, + content: @Composable RowScope.() -> Unit +) = + Button(onClick, modifier, enabled, content) diff --git a/compose-multiplatform-material3/src/commonMain/kotlin/com/huanshankeji/compose/material3/ext/Button.kt b/compose-multiplatform-material3/src/commonMain/kotlin/com/huanshankeji/compose/material3/ext/Button.kt new file mode 100644 index 00000000..ea6fed53 --- /dev/null +++ b/compose-multiplatform-material3/src/commonMain/kotlin/com/huanshankeji/compose/material3/ext/Button.kt @@ -0,0 +1,17 @@ +package com.huanshankeji.compose.material3.ext + +import androidx.compose.runtime.Composable +import com.huanshankeji.compose.ui.Modifier + +@Composable +expect fun Button( + onClick: () -> Unit, + modifier: Modifier = Modifier, + enabled: Boolean = true, + content: @Composable ButtonScope.() -> Unit +) + +expect class ButtonScope { + @Composable + fun Icon() +} diff --git a/compose-multiplatform-material3/src/jsMain/kotlin/com/huanshankeji/compose/html/material3/MdButton.kt b/compose-multiplatform-material3/src/jsMain/kotlin/com/huanshankeji/compose/html/material3/MdButton.kt new file mode 100644 index 00000000..47438779 --- /dev/null +++ b/compose-multiplatform-material3/src/jsMain/kotlin/com/huanshankeji/compose/html/material3/MdButton.kt @@ -0,0 +1,69 @@ +package com.huanshankeji.compose.html.material3 + +import androidx.compose.runtime.Composable +import com.varabyte.kobweb.compose.css.disabled +import org.jetbrains.compose.web.attributes.AttrsScope +import org.jetbrains.compose.web.dom.ElementScope +import org.jetbrains.compose.web.dom.TagElement +import org.w3c.dom.HTMLElement +import org.w3c.dom.HTMLFormElement + +external fun require(module: String): dynamic + +/* +// TODO not working +@JsModule("@material/web/button/elevated-button.js") +external class MdElevatedButton /* : Element */ // TODO + +private var toImport = true +*/ + +// https://github.com/material-components/material-web/blob/main/docs/components/button.md +@Composable +fun MdElevatedButton( + disabled: Boolean? = null, + href: String? = null, + target: String? = null, + trailingIcon: Boolean? = null, + hasIcon: Boolean? = null, + type: String? = null, + value: String? = null, + name: String? = null, + form: HTMLFormElement? = null, + ariaLabel: String? = null, + attrs: (AttrsScope.() -> Unit)?, + content: (@Composable MdButtonScope.() -> Unit)? +) { + /* + // TODO not working + if (toImport) { + MdElevatedButton() + toImport = false + } + */ + // It seems there is no need to put this in an effect block, because it seems on Compose HTML recomposition happens exactly when there is a need to re-invoke a composable. + require("@material/web/button/elevated-button.js") + + //TagElement({ MdElevatedButton().asDynamic() }, { TODO() }) { TODO() } + @Suppress("RemoveExplicitTypeArguments") + TagElement("md-elevated-button", { + disabled?.let { disabled(it) } + href?.let { attr("href", it) } + target?.let { attr("target", it) } + trailingIcon?.let { attr("trailing-icon", it.toString()) } + hasIcon?.let { attr("has-icon", it.toString()) } + type?.let { attr("type", it) } + value?.let { attr("value", it) } + name?.let { attr("name", it) } + form?.let { TODO() } + // ariaLabel?.let { TODO() } // TODO remove as it's a universal attribute + attrs?.invoke(this) + }, content?.let { + { MdButtonScope(this).it() } + }) +} + +class MdButtonScope(val elementScope: ElementScope) { + fun AttrsScope<*>.slotIcon() = + attr("slot", "icon") +} diff --git a/compose-multiplatform-material3/src/jsMain/kotlin/com/huanshankeji/compose/material3/Button.js.kt b/compose-multiplatform-material3/src/jsMain/kotlin/com/huanshankeji/compose/material3/Button.js.kt new file mode 100644 index 00000000..8e2bcf82 --- /dev/null +++ b/compose-multiplatform-material3/src/jsMain/kotlin/com/huanshankeji/compose/material3/Button.js.kt @@ -0,0 +1,34 @@ +package com.huanshankeji.compose.material3 + +import androidx.compose.runtime.Composable +import com.huanshankeji.compose.foundation.layout.Row +import com.huanshankeji.compose.foundation.layout.RowScope +import com.huanshankeji.compose.html.material3.MdButtonScope +import com.huanshankeji.compose.html.material3.MdElevatedButton +import com.huanshankeji.compose.ui.Modifier +import com.varabyte.kobweb.compose.ui.toAttrs + +@Composable +internal fun CommonButton( + onClick: () -> Unit, + modifier: Modifier, + enabled: Boolean, + content: @Composable MdButtonScope.() -> Unit +) = + MdElevatedButton(disabled = if (enabled) null else true, + attrs = modifier.platformModifier.toAttrs { + onClick { onClick() } + }) { + content() + } + +@Composable +actual fun Button( + onClick: () -> Unit, + modifier: Modifier, + enabled: Boolean, + content: @Composable RowScope.() -> Unit +) = + CommonButton(onClick, modifier, enabled) { + Row(content = content) + } diff --git a/compose-multiplatform-material3/src/jsMain/kotlin/com/huanshankeji/compose/material3/ext/Button.js.kt b/compose-multiplatform-material3/src/jsMain/kotlin/com/huanshankeji/compose/material3/ext/Button.js.kt new file mode 100644 index 00000000..b4181b23 --- /dev/null +++ b/compose-multiplatform-material3/src/jsMain/kotlin/com/huanshankeji/compose/material3/ext/Button.js.kt @@ -0,0 +1,24 @@ +package com.huanshankeji.compose.material3.ext + +import androidx.compose.runtime.Composable +import com.huanshankeji.compose.html.material3.MdButtonScope +import com.huanshankeji.compose.material3.CommonButton +import com.huanshankeji.compose.ui.Modifier + +@Composable +actual fun Button( + onClick: () -> Unit, + modifier: Modifier, + enabled: Boolean, + content: @Composable ButtonScope.() -> Unit +) = + CommonButton(onClick, modifier, enabled) { + ButtonScope(this).content() + } + +actual class ButtonScope(val mdButtonScope: MdButtonScope) { + @Composable + actual fun Icon() { + TODO() + } +} diff --git a/demo/build.gradle.kts b/demo/build.gradle.kts index 04bf8fc3..bf9c1121 100644 --- a/demo/build.gradle.kts +++ b/demo/build.gradle.kts @@ -47,6 +47,7 @@ kotlin { dependencies { implementation(compose.runtime) implementation(project(":compose-multiplatform-material")) + implementation(project(":compose-multiplatform-material3")) } } jvmMain { diff --git a/demo/src/commonMain/kotlin/com/huanshankeji/compose/material/demo/App.kt b/demo/src/commonMain/kotlin/com/huanshankeji/compose/material/demo/App.kt index 472f35a3..ae824852 100644 --- a/demo/src/commonMain/kotlin/com/huanshankeji/compose/material/demo/App.kt +++ b/demo/src/commonMain/kotlin/com/huanshankeji/compose/material/demo/App.kt @@ -22,6 +22,8 @@ import com.huanshankeji.compose.ui.height import com.huanshankeji.compose.ui.unit.dpOrPx import com.huanshankeji.compose.ui.width import com.huanshankeji.compose.material.ext.Button as ExtButton +import com.huanshankeji.compose.material3.Button as M3Button +import com.huanshankeji.compose.material3.ext.Button as M3ExtButton @OptIn(ConfusableTextApi::class) @Composable @@ -52,18 +54,24 @@ fun App() { var count by remember { mutableStateOf(0) } val onClick: () -> Unit = { count++ } + val buttonContent: @Composable () -> Unit = { + Text(count.toString()) // TODO use `com.huanshankeji.compose.material(3).ext.InlineText` + } + val rowScopeButtonContent: @Composable RowScope.() -> Unit = { buttonContent()} + Row { - val buttonContent: @Composable RowScope.() -> Unit = { - Text(count.toString()) - } - Button(onClick, content = buttonContent) - OutlinedButton(onClick, content = buttonContent) - TextButton(onClick, content = buttonContent) + Button(onClick, content = rowScopeButtonContent) + OutlinedButton(onClick, content = rowScopeButtonContent) + TextButton(onClick, content = rowScopeButtonContent) ExtButton(onClick) { Label(count.toString()) } IconButton(onClick, materialIcon = MaterialIcons.Add, contentDescription = "increment count") } + Row { + M3Button(onClick, content = rowScopeButtonContent) + M3ExtButton(onClick) { buttonContent() } + } Box(Modifier.padding(16.dp)) { ScrollableList({ diff --git a/kotlin-js-store/yarn.lock b/kotlin-js-store/yarn.lock index b57acf80..50f1b578 100644 --- a/kotlin-js-store/yarn.lock +++ b/kotlin-js-store/yarn.lock @@ -57,11 +57,28 @@ "@jridgewell/resolve-uri" "^3.1.0" "@jridgewell/sourcemap-codec" "^1.4.14" +"@js-joda/core@3.2.0": + version "3.2.0" + resolved "https://registry.yarnpkg.com/@js-joda/core/-/core-3.2.0.tgz#3e61e21b7b2b8a6be746df1335cf91d70db2a273" + integrity sha512-PMqgJ0sw5B7FKb2d5bWYIoxjri+QlW/Pys7+Rw82jSH0QN3rB05jZ/VrrsUdh1w4+i2kw9JOejXGq/KhDOX7Kg== + "@leichtgewicht/ip-codec@^2.0.1": version "2.0.4" resolved "https://registry.yarnpkg.com/@leichtgewicht/ip-codec/-/ip-codec-2.0.4.tgz#b2ac626d6cb9c8718ab459166d4bb405b8ffa78b" integrity sha512-Hcv+nVC0kZnQ3tD9GVu5xSMR4VVYOteQIr/hwFPVEvPdlXqgGEuRjiheChHgdM+JyqdgNcmzZOX/tnl0JOiI7A== +"@lit-labs/ssr-dom-shim@^1.2.0": + version "1.2.0" + resolved "https://registry.yarnpkg.com/@lit-labs/ssr-dom-shim/-/ssr-dom-shim-1.2.0.tgz#353ce4a76c83fadec272ea5674ede767650762fd" + integrity sha512-yWJKmpGE6lUURKAaIltoPIE/wrbY3TEkqQt+X0m+7fQNnAv0keydnYvbiJFP1PnMhizmIWRWOG5KLhYyc/xl+g== + +"@lit/reactive-element@^2.0.4": + version "2.0.4" + resolved "https://registry.yarnpkg.com/@lit/reactive-element/-/reactive-element-2.0.4.tgz#8f2ed950a848016383894a26180ff06c56ae001b" + integrity sha512-GFn91inaUa2oHLak8awSIigYz0cU0Payr1rcFsrkf5OJ5eSPxElyZfKh0f2p9FsTiZWXQdWGJeXZICEfXXYSXQ== + dependencies: + "@lit-labs/ssr-dom-shim" "^1.2.0" + "@material/animation@^14.0.0": version "14.0.0" resolved "https://registry.yarnpkg.com/@material/animation/-/animation-14.0.0.tgz#f23fbe38deb6a48829dcdb0b7580017a4217e94b" @@ -738,6 +755,14 @@ "@material/theme" "^14.0.0" tslib "^2.1.0" +"@material/web@1.4.0": + version "1.4.0" + resolved "https://registry.yarnpkg.com/@material/web/-/web-1.4.0.tgz#2354ae1bcbfd1a81bececfdc35f5bfe8cbce0777" + integrity sha512-+rnQLUc/vsu7vnkr8XxbEhNVEcdkaYxNjykZ18w/nUMrYTEvAi4TRQJAYeEUXMwRcO3mEXBsCKOtHZ+cbmxTLw== + dependencies: + lit "^2.7.4 || ^3.0.0" + tslib "^2.4.0" + "@socket.io/component-emitter@~3.1.0": version "3.1.0" resolved "https://registry.yarnpkg.com/@socket.io/component-emitter/-/component-emitter-3.1.0.tgz#96116f2a912e0c02817345b3c10751069920d553" @@ -894,6 +919,11 @@ dependencies: "@types/node" "*" +"@types/trusted-types@^2.0.2": + version "2.0.7" + resolved "https://registry.yarnpkg.com/@types/trusted-types/-/trusted-types-2.0.7.tgz#baccb07a970b91707df3a3e8ba6896c57ead2d11" + integrity sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw== + "@types/ws@^8.5.1": version "8.5.3" resolved "https://registry.yarnpkg.com/@types/ws/-/ws-8.5.3.tgz#7d25a1ffbecd3c4f2d35068d0b283c037003274d" @@ -2308,6 +2338,31 @@ launch-editor@^2.6.0: picocolors "^1.0.0" shell-quote "^1.8.1" +lit-element@^4.0.4: + version "4.0.4" + resolved "https://registry.yarnpkg.com/lit-element/-/lit-element-4.0.4.tgz#e0b37ebbe2394bcb9578d611a409f49475dff361" + integrity sha512-98CvgulX6eCPs6TyAIQoJZBCQPo80rgXR+dVBs61cstJXqtI+USQZAbA4gFHh6L/mxBx9MrgPLHLsUgDUHAcCQ== + dependencies: + "@lit-labs/ssr-dom-shim" "^1.2.0" + "@lit/reactive-element" "^2.0.4" + lit-html "^3.1.2" + +lit-html@^3.1.2: + version "3.1.2" + resolved "https://registry.yarnpkg.com/lit-html/-/lit-html-3.1.2.tgz#6655ce82367472de7680c62b1bcb0beb0e426fa1" + integrity sha512-3OBZSUrPnAHoKJ9AMjRL/m01YJxQMf+TMHanNtTHG68ubjnZxK0RFl102DPzsw4mWnHibfZIBJm3LWCZ/LmMvg== + dependencies: + "@types/trusted-types" "^2.0.2" + +"lit@^2.7.4 || ^3.0.0": + version "3.1.2" + resolved "https://registry.yarnpkg.com/lit/-/lit-3.1.2.tgz#f276258e8a56593f1d834a5fd00a7eb5e891ae73" + integrity sha512-VZx5iAyMtX7CV4K8iTLdCkMaYZ7ipjJZ0JcSdJ0zIdGxxyurjIn7yuuSxNBD7QmjvcNJwr0JS4cAdAtsy7gZ6w== + dependencies: + "@lit/reactive-element" "^2.0.4" + lit-element "^4.0.4" + lit-html "^3.1.2" + loader-runner@^4.2.0: version "4.3.0" resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-4.3.0.tgz#c1b4a163b99f614830353b16755e7149ac2314e1" @@ -3290,6 +3345,11 @@ tslib@^2.1.0: resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.4.1.tgz#0d0bfbaac2880b91e22df0768e55be9753a5b17e" integrity sha512-tGyy4dAjRIEwI7BzsB0lynWgOpfqjUdq91XXAlIWD2OwKBH7oCl/GZG/HT4BOHrTlPMOASlMQ7veyTqpmRcrNA== +tslib@^2.4.0: + version "2.6.2" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.6.2.tgz#703ac29425e7b37cd6fd456e92404d46d1f3e4ae" + integrity sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q== + type-is@~1.6.18: version "1.6.18" resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.18.tgz#4e552cd05df09467dcbc4ef739de89f2cf37c131" diff --git a/settings.gradle.kts b/settings.gradle.kts index 1c913d14..c5f51294 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -4,6 +4,7 @@ include("compose-multiplatform-common") // TODO consider splitting into several include("compose-multiplatform-common:legacy") project(":compose-multiplatform-common:legacy").name = "compose-multiplatform-common-legacy" include("compose-multiplatform-material") +include("compose-multiplatform-material3") include("demo") From 68cb624bf19ce41ec3fe932b26a191aee2b7540c Mon Sep 17 00:00:00 2001 From: Shreck Ye Date: Mon, 15 Apr 2024 04:02:26 +0800 Subject: [PATCH 03/75] Move code (the `MdButton` composable) to "compose-html-material" and depend on the module into which the code is moved There is a build error: ```text > Task :demo:compileDevelopmentExecutableKotlinJs FAILED e: java.lang.IllegalStateException: IrPropertyPublicSymbolImpl for org.jetbrains.compose.web.attributes/setInputValue|{}setInputValue[0] is already bound: PROPERTY name:setInputValue visibility:internal modality:FINAL [val] ``` The corresponding commit: https://github.com/huanshankeji/compose-html-material/commit/d6d797ef50611ace39cccab125d2b23727885311 --- .../main/kotlin/VersionsAndDependencies.kt | 6 +- .../legacy/build.gradle.kts | 2 +- .../build.gradle.kts | 3 +- .../compose/html/material3/MdButton.kt | 69 ------------------- 4 files changed, 4 insertions(+), 76 deletions(-) delete mode 100644 compose-multiplatform-material3/src/jsMain/kotlin/com/huanshankeji/compose/html/material3/MdButton.kt diff --git a/buildSrc/src/main/kotlin/VersionsAndDependencies.kt b/buildSrc/src/main/kotlin/VersionsAndDependencies.kt index fc4f1615..8eec253f 100644 --- a/buildSrc/src/main/kotlin/VersionsAndDependencies.kt +++ b/buildSrc/src/main/kotlin/VersionsAndDependencies.kt @@ -1,7 +1,7 @@ object DependencyVersions { - val composeMultiplatform = "1.6.1" // manually specified for "ui-unit" + val composeMultiplatform = "1.6.1" // manually specified for `ui-unit` val kobweb = "0.17.1" - val huanshankejiComposeWeb = "0.2.2" + val huanshankejiComposeHtml = "0.3.0-SNAPSHOT" // TODO don't use a snapshot in a main branch val kmdc = "0.1.2" val materialIcons = "1.13.12" @@ -9,6 +9,4 @@ object DependencyVersions { val activityCompose = "1.8.2" val compose = "1.6.4" } - - val materialWeb = "1.4.0" } diff --git a/compose-multiplatform-common/legacy/build.gradle.kts b/compose-multiplatform-common/legacy/build.gradle.kts index 4bef7951..c8443da0 100644 --- a/compose-multiplatform-common/legacy/build.gradle.kts +++ b/compose-multiplatform-common/legacy/build.gradle.kts @@ -22,7 +22,7 @@ kotlin { dependencies { implementation(compose.html.core) - api("com.huanshankeji:compose-web-common:${DependencyVersions.huanshankejiComposeWeb}") + api("com.huanshankeji:compose-web-common:${DependencyVersions.huanshankejiComposeHtml}") } } } diff --git a/compose-multiplatform-material3/build.gradle.kts b/compose-multiplatform-material3/build.gradle.kts index a102f5df..55429431 100644 --- a/compose-multiplatform-material3/build.gradle.kts +++ b/compose-multiplatform-material3/build.gradle.kts @@ -26,8 +26,7 @@ kotlin { } jsMain { dependencies { - //implementation("com.huanshankeji:compose-web-common:${DependencyVersions.huanshankejiComposeWeb}") // TODO remove - implementation(npm("@material/web", DependencyVersions.materialWeb)) + api("com.huanshankeji:compose-html-material3:${DependencyVersions.huanshankejiComposeHtml}") } } } diff --git a/compose-multiplatform-material3/src/jsMain/kotlin/com/huanshankeji/compose/html/material3/MdButton.kt b/compose-multiplatform-material3/src/jsMain/kotlin/com/huanshankeji/compose/html/material3/MdButton.kt deleted file mode 100644 index 47438779..00000000 --- a/compose-multiplatform-material3/src/jsMain/kotlin/com/huanshankeji/compose/html/material3/MdButton.kt +++ /dev/null @@ -1,69 +0,0 @@ -package com.huanshankeji.compose.html.material3 - -import androidx.compose.runtime.Composable -import com.varabyte.kobweb.compose.css.disabled -import org.jetbrains.compose.web.attributes.AttrsScope -import org.jetbrains.compose.web.dom.ElementScope -import org.jetbrains.compose.web.dom.TagElement -import org.w3c.dom.HTMLElement -import org.w3c.dom.HTMLFormElement - -external fun require(module: String): dynamic - -/* -// TODO not working -@JsModule("@material/web/button/elevated-button.js") -external class MdElevatedButton /* : Element */ // TODO - -private var toImport = true -*/ - -// https://github.com/material-components/material-web/blob/main/docs/components/button.md -@Composable -fun MdElevatedButton( - disabled: Boolean? = null, - href: String? = null, - target: String? = null, - trailingIcon: Boolean? = null, - hasIcon: Boolean? = null, - type: String? = null, - value: String? = null, - name: String? = null, - form: HTMLFormElement? = null, - ariaLabel: String? = null, - attrs: (AttrsScope.() -> Unit)?, - content: (@Composable MdButtonScope.() -> Unit)? -) { - /* - // TODO not working - if (toImport) { - MdElevatedButton() - toImport = false - } - */ - // It seems there is no need to put this in an effect block, because it seems on Compose HTML recomposition happens exactly when there is a need to re-invoke a composable. - require("@material/web/button/elevated-button.js") - - //TagElement({ MdElevatedButton().asDynamic() }, { TODO() }) { TODO() } - @Suppress("RemoveExplicitTypeArguments") - TagElement("md-elevated-button", { - disabled?.let { disabled(it) } - href?.let { attr("href", it) } - target?.let { attr("target", it) } - trailingIcon?.let { attr("trailing-icon", it.toString()) } - hasIcon?.let { attr("has-icon", it.toString()) } - type?.let { attr("type", it) } - value?.let { attr("value", it) } - name?.let { attr("name", it) } - form?.let { TODO() } - // ariaLabel?.let { TODO() } // TODO remove as it's a universal attribute - attrs?.invoke(this) - }, content?.let { - { MdButtonScope(this).it() } - }) -} - -class MdButtonScope(val elementScope: ElementScope) { - fun AttrsScope<*>.slotIcon() = - attr("slot", "icon") -} From 27c35d7677cd04c916ded33a70df6098a40f38cd Mon Sep 17 00:00:00 2001 From: Shreck Ye Date: Mon, 15 Apr 2024 05:07:10 +0800 Subject: [PATCH 04/75] Change "compose-web" into "compose-html" and fix the build error mentioned in the previous commit --- compose-multiplatform-common/legacy/build.gradle.kts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/compose-multiplatform-common/legacy/build.gradle.kts b/compose-multiplatform-common/legacy/build.gradle.kts index c8443da0..8f0df908 100644 --- a/compose-multiplatform-common/legacy/build.gradle.kts +++ b/compose-multiplatform-common/legacy/build.gradle.kts @@ -22,7 +22,7 @@ kotlin { dependencies { implementation(compose.html.core) - api("com.huanshankeji:compose-web-common:${DependencyVersions.huanshankejiComposeHtml}") + api("com.huanshankeji:compose-html-common:${DependencyVersions.huanshankejiComposeHtml}") } } } @@ -33,7 +33,7 @@ publishing.publications.withType { project, "Legacy Compose Multiplatform common wrappers", "Legacy common wrappers of components (including layouts) and styles for Compose Multiplatform on (desktop/Android and web)\n" + - "This legacy module depends on `com.huanshankeji:compose-web-common` instead of Kobweb Silk " + + "This legacy module depends on `com.huanshankeji:compose-html-common` instead of Kobweb Silk " + "and its components use the `ModifierOrAttrsScope` class to configure styles." ) { `Shreck Ye`() From 68acbc6fb974bb59a5ce8f8813adc99e139aedbc Mon Sep 17 00:00:00 2001 From: Shreck Ye Date: Mon, 15 Apr 2024 05:07:10 +0800 Subject: [PATCH 05/75] Change "compose-web" into "compose-html" and fix the build error mentioned in the previous commit Apparently it was caused by duplicate code in the dependencies `compose-web-common:0.3.0-SNAPSHOT` and `compose-html-common:0.3.0-SNAPSHOT`. --- compose-multiplatform-common/legacy/build.gradle.kts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/compose-multiplatform-common/legacy/build.gradle.kts b/compose-multiplatform-common/legacy/build.gradle.kts index c8443da0..8f0df908 100644 --- a/compose-multiplatform-common/legacy/build.gradle.kts +++ b/compose-multiplatform-common/legacy/build.gradle.kts @@ -22,7 +22,7 @@ kotlin { dependencies { implementation(compose.html.core) - api("com.huanshankeji:compose-web-common:${DependencyVersions.huanshankejiComposeHtml}") + api("com.huanshankeji:compose-html-common:${DependencyVersions.huanshankejiComposeHtml}") } } } @@ -33,7 +33,7 @@ publishing.publications.withType { project, "Legacy Compose Multiplatform common wrappers", "Legacy common wrappers of components (including layouts) and styles for Compose Multiplatform on (desktop/Android and web)\n" + - "This legacy module depends on `com.huanshankeji:compose-web-common` instead of Kobweb Silk " + + "This legacy module depends on `com.huanshankeji:compose-html-common` instead of Kobweb Silk " + "and its components use the `ModifierOrAttrsScope` class to configure styles." ) { `Shreck Ye`() From 741cc1fa8f10b2ad2298788fe0f1828834687341 Mon Sep 17 00:00:00 2001 From: Shreck Ye Date: Wed, 17 Apr 2024 18:17:36 +0800 Subject: [PATCH 06/75] Update README.md about components --- README.md | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 4e38e401..6a97f123 100644 --- a/README.md +++ b/README.md @@ -37,10 +37,16 @@ This project is prototype and there is no documentation yet. Check out [the demo - `Card` - `Icon` - `IconButton` -- `ScrollableList`/`LazyColumn` (visually inconsistent for now) +- `LazyColumn`/`ScrollableList` (visually inconsistent for now) - `Text`/`MaterialText` - `TextField` + +##### `ext` components + +- `Button` +- `IconButton` - `TopAppBarScaffold` +- `InlineText` #### Components in the `ext` packages From 2bae9eb331d16ecaa6f6c2160bd4ba98b2ff1101 Mon Sep 17 00:00:00 2001 From: Shreck Ye Date: Wed, 17 Apr 2024 18:22:44 +0800 Subject: [PATCH 07/75] Update a KDoc --- .../com/huanshankeji/compose/material/lazy/ext/LazyDsl.kt | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/compose-multiplatform-material/src/commonMain/kotlin/com/huanshankeji/compose/material/lazy/ext/LazyDsl.kt b/compose-multiplatform-material/src/commonMain/kotlin/com/huanshankeji/compose/material/lazy/ext/LazyDsl.kt index a58aecf1..358ead26 100644 --- a/compose-multiplatform-material/src/commonMain/kotlin/com/huanshankeji/compose/material/lazy/ext/LazyDsl.kt +++ b/compose-multiplatform-material/src/commonMain/kotlin/com/huanshankeji/compose/material/lazy/ext/LazyDsl.kt @@ -1,10 +1,9 @@ package com.huanshankeji.compose.material.lazy.ext -//import androidx.compose.foundation.lazy.LazyListScope import androidx.compose.runtime.Composable import com.huanshankeji.compose.ui.Modifier -/** @see LazyListScope */ +/** @see androidx.compose.foundation.lazy.LazyListScope */ expect class LazyListScope { fun item(key: Any? = null, contentType: Any? = null, content: @Composable LazyItemScope.() -> Unit) From 67f70b3851886ecddd1c5228a01feb7a9b91d66e Mon Sep 17 00:00:00 2001 From: Shreck Ye Date: Thu, 18 Apr 2024 11:23:42 +0800 Subject: [PATCH 08/75] Update the project version to "0.3.0-SNAPSHOT" --- buildSrc/src/main/kotlin/VersionsAndDependencies.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/buildSrc/src/main/kotlin/VersionsAndDependencies.kt b/buildSrc/src/main/kotlin/VersionsAndDependencies.kt index b01d9ff9..b72c83c8 100644 --- a/buildSrc/src/main/kotlin/VersionsAndDependencies.kt +++ b/buildSrc/src/main/kotlin/VersionsAndDependencies.kt @@ -1,4 +1,4 @@ -val projectVersion = "0.2.0-SNAPSHOT" +val projectVersion = "0.3.0-SNAPSHOT" object DependencyVersions { val composeMultiplatform = "1.6.1" // manually specified for `ui-unit` From e34fe0308132136adb944a92ee7a3155e4734f20 Mon Sep 17 00:00:00 2001 From: Shreck Ye Date: Thu, 18 Apr 2024 11:27:14 +0800 Subject: [PATCH 09/75] Remove a block of redundant commented-out code --- .../kotlin/com/huanshankeji/compose/material/demo/App.kt | 4 ---- 1 file changed, 4 deletions(-) diff --git a/demo/src/commonMain/kotlin/com/huanshankeji/compose/material/demo/App.kt b/demo/src/commonMain/kotlin/com/huanshankeji/compose/material/demo/App.kt index 127c08fe..ee7d699f 100644 --- a/demo/src/commonMain/kotlin/com/huanshankeji/compose/material/demo/App.kt +++ b/demo/src/commonMain/kotlin/com/huanshankeji/compose/material/demo/App.kt @@ -37,10 +37,6 @@ fun App() { }, actions = { MaterialIconActionButton({}, Icons.Default.Search, "search") }) { - /* - // TODO use this - Modifier.padding(16.dp).height(800.dp).width(400.dp) - */ Card(Modifier.padding(16.dp).height(800.dp).width(400.dp)) { Column(Modifier.padding(16.dp)) { BasicText("basic text 1") From c7adf748b3273373d5de83a9f978758dcd926e36 Mon Sep 17 00:00:00 2001 From: Shreck Ye Date: Thu, 18 Apr 2024 11:36:58 +0800 Subject: [PATCH 10/75] Add the modifier parameter to `RadioButton` --- .../com/huanshankeji/compose/material/RadioButton.kt | 3 ++- .../com/huanshankeji/compose/material/RadioButton.kt | 9 +++++++-- .../com/huanshankeji/compose/material/RadioButton.kt | 3 ++- 3 files changed, 11 insertions(+), 4 deletions(-) diff --git a/compose-multiplatform-material/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material/RadioButton.kt b/compose-multiplatform-material/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material/RadioButton.kt index b12dd313..b93fffbd 100644 --- a/compose-multiplatform-material/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material/RadioButton.kt +++ b/compose-multiplatform-material/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material/RadioButton.kt @@ -1,7 +1,8 @@ package com.huanshankeji.compose.material import androidx.compose.runtime.Composable +import com.huanshankeji.compose.ui.Modifier @Composable -actual fun RadioButton(selected: Boolean, onClick: (() -> Unit)?, enabled: Boolean) = +actual fun RadioButton(selected: Boolean, onClick: (() -> Unit)?, modifier: Modifier, enabled: Boolean) = androidx.compose.material.RadioButton(selected, onClick, enabled = enabled) diff --git a/compose-multiplatform-material/src/commonMain/kotlin/com/huanshankeji/compose/material/RadioButton.kt b/compose-multiplatform-material/src/commonMain/kotlin/com/huanshankeji/compose/material/RadioButton.kt index 08b42869..e3255be2 100644 --- a/compose-multiplatform-material/src/commonMain/kotlin/com/huanshankeji/compose/material/RadioButton.kt +++ b/compose-multiplatform-material/src/commonMain/kotlin/com/huanshankeji/compose/material/RadioButton.kt @@ -1,8 +1,13 @@ package com.huanshankeji.compose.material import androidx.compose.runtime.Composable +import com.huanshankeji.compose.ui.Modifier -// TODO modifier // TODO colors @Composable -expect fun RadioButton(selected: Boolean, onClick: (() -> Unit)?, enabled: Boolean = true) +expect fun RadioButton( + selected: Boolean, + onClick: (() -> Unit)?, + modifier: Modifier = Modifier, + enabled: Boolean = true +) diff --git a/compose-multiplatform-material/src/jsMain/kotlin/com/huanshankeji/compose/material/RadioButton.kt b/compose-multiplatform-material/src/jsMain/kotlin/com/huanshankeji/compose/material/RadioButton.kt index 814c7184..7c832957 100644 --- a/compose-multiplatform-material/src/jsMain/kotlin/com/huanshankeji/compose/material/RadioButton.kt +++ b/compose-multiplatform-material/src/jsMain/kotlin/com/huanshankeji/compose/material/RadioButton.kt @@ -1,10 +1,11 @@ package com.huanshankeji.compose.material import androidx.compose.runtime.Composable +import com.huanshankeji.compose.ui.Modifier import dev.petuska.kmdc.radio.MDCRadio @Composable -actual fun RadioButton(selected: Boolean, onClick: (() -> Unit)?, enabled: Boolean) = +actual fun RadioButton(selected: Boolean, onClick: (() -> Unit)?, modifier: Modifier, enabled: Boolean) = MDCRadio(selected, disabled = !enabled, attrs = { if (onClick !== null) onClick { onClick() } }) From ed5c709093581c221f123e8d84c2a6032d293f08 Mon Sep 17 00:00:00 2001 From: Shreck Ye Date: Thu, 18 Apr 2024 12:00:47 +0800 Subject: [PATCH 11/75] Add support for `Modifier.onClick` and use it as a temporary solution in the demo --- .../compose/foundation/OnClick.androidxCommon.kt | 9 +++++++++ .../compose/foundation/ExperimentalFoundationApi.kt | 8 ++++++++ .../com/huanshankeji/compose/foundation/OnClick.kt | 5 +++++ .../com/huanshankeji/compose/foundation/OnClick.js.kt | 7 +++++++ .../kotlin/com/huanshankeji/compose/material/demo/App.kt | 8 +++----- 5 files changed, 32 insertions(+), 5 deletions(-) create mode 100644 compose-multiplatform-common/src/androidxCommonMain/kotlin/com/huanshankeji/compose/foundation/OnClick.androidxCommon.kt create mode 100644 compose-multiplatform-common/src/commonMain/kotlin/com/huanshankeji/compose/foundation/ExperimentalFoundationApi.kt create mode 100644 compose-multiplatform-common/src/commonMain/kotlin/com/huanshankeji/compose/foundation/OnClick.kt create mode 100644 compose-multiplatform-common/src/jsMain/kotlin/com/huanshankeji/compose/foundation/OnClick.js.kt diff --git a/compose-multiplatform-common/src/androidxCommonMain/kotlin/com/huanshankeji/compose/foundation/OnClick.androidxCommon.kt b/compose-multiplatform-common/src/androidxCommonMain/kotlin/com/huanshankeji/compose/foundation/OnClick.androidxCommon.kt new file mode 100644 index 00000000..0ccd6995 --- /dev/null +++ b/compose-multiplatform-common/src/androidxCommonMain/kotlin/com/huanshankeji/compose/foundation/OnClick.androidxCommon.kt @@ -0,0 +1,9 @@ +package com.huanshankeji.compose.foundation + +import androidx.compose.foundation.onClick +import com.huanshankeji.compose.ui.Modifier + +//@ExperimentalFoundationApi // `onClick` with a single parameter is likely to be always supported, so it does not require opt-in for now. +@OptIn(androidx.compose.foundation.ExperimentalFoundationApi::class) +actual fun Modifier.onClick(onClick: () -> Unit): Modifier = + platformModify { onClick(onClick = onClick) } diff --git a/compose-multiplatform-common/src/commonMain/kotlin/com/huanshankeji/compose/foundation/ExperimentalFoundationApi.kt b/compose-multiplatform-common/src/commonMain/kotlin/com/huanshankeji/compose/foundation/ExperimentalFoundationApi.kt new file mode 100644 index 00000000..c9e1b68d --- /dev/null +++ b/compose-multiplatform-common/src/commonMain/kotlin/com/huanshankeji/compose/foundation/ExperimentalFoundationApi.kt @@ -0,0 +1,8 @@ +package com.huanshankeji.compose.foundation + +@RequiresOptIn( + "This foundation API is experimental and is likely to change or be removed in the " + + "future. See `androidx.compose.foundation.ExperimentalFoundationApi`." +) +@Retention(AnnotationRetention.BINARY) +annotation class ExperimentalFoundationApi diff --git a/compose-multiplatform-common/src/commonMain/kotlin/com/huanshankeji/compose/foundation/OnClick.kt b/compose-multiplatform-common/src/commonMain/kotlin/com/huanshankeji/compose/foundation/OnClick.kt new file mode 100644 index 00000000..e9415572 --- /dev/null +++ b/compose-multiplatform-common/src/commonMain/kotlin/com/huanshankeji/compose/foundation/OnClick.kt @@ -0,0 +1,5 @@ +package com.huanshankeji.compose.foundation + +import com.huanshankeji.compose.ui.Modifier + +expect fun Modifier.onClick(onClick: () -> Unit): Modifier diff --git a/compose-multiplatform-common/src/jsMain/kotlin/com/huanshankeji/compose/foundation/OnClick.js.kt b/compose-multiplatform-common/src/jsMain/kotlin/com/huanshankeji/compose/foundation/OnClick.js.kt new file mode 100644 index 00000000..2856d5fb --- /dev/null +++ b/compose-multiplatform-common/src/jsMain/kotlin/com/huanshankeji/compose/foundation/OnClick.js.kt @@ -0,0 +1,7 @@ +package com.huanshankeji.compose.foundation + +import com.huanshankeji.compose.ui.Modifier +import com.varabyte.kobweb.compose.ui.modifiers.onClick + +actual fun Modifier.onClick(onClick: () -> Unit): Modifier = + platformModify { onClick { onClick() } } diff --git a/demo/src/commonMain/kotlin/com/huanshankeji/compose/material/demo/App.kt b/demo/src/commonMain/kotlin/com/huanshankeji/compose/material/demo/App.kt index d5e96482..081fda71 100644 --- a/demo/src/commonMain/kotlin/com/huanshankeji/compose/material/demo/App.kt +++ b/demo/src/commonMain/kotlin/com/huanshankeji/compose/material/demo/App.kt @@ -11,6 +11,7 @@ import com.huanshankeji.compose.foundation.layout.Box import com.huanshankeji.compose.foundation.layout.Column import com.huanshankeji.compose.foundation.layout.Row import com.huanshankeji.compose.foundation.layout.RowScope +import com.huanshankeji.compose.foundation.onClick import com.huanshankeji.compose.foundation.text.BasicText import com.huanshankeji.compose.layout.height import com.huanshankeji.compose.layout.padding @@ -126,11 +127,8 @@ fun App() { @Composable fun RadioButtonRow(state: RadioButtonState) = // TODO `Modifier.selectable()` - Row { - RadioButton( - selected == state, - { selected = state } // TODO put in the `Row` `modifier` - ) + Row(Modifier.onClick { selected = state } /* TODO put in `Modifier.selectable` */) { + RadioButton(selected == state, {}) // TODO put center vertically Text( text = state.toString() From e45180d52f4753aed21067f754111234d3cf1208 Mon Sep 17 00:00:00 2001 From: Shreck Ye Date: Thu, 18 Apr 2024 19:47:14 +0800 Subject: [PATCH 12/75] Refactor `RadioButton` into `RadioRow` and add `RadioGroupRow` and put them in the `ext` package, and update the demo accordingly This is because `androidx.compose.material.RadioButton` and `dev.petuska.kmdc.radio.MDCRadio` are not the same thing. `MDCRadio` takes an additional `label` argument. --- README.md | 3 ++- .../compose/material/RadioButton.kt | 8 ------- .../material/ext/Radio.androidxCommon.kt | 24 +++++++++++++++++++ .../compose/material/RadioButton.kt | 13 ---------- .../compose/material/ext/Radio.kt | 19 +++++++++++++++ .../compose/material/RadioButton.kt | 11 --------- .../compose/material/ext/Radio.js.kt | 21 ++++++++++++++++ .../huanshankeji/compose/material/demo/App.kt | 15 ++++-------- 8 files changed, 70 insertions(+), 44 deletions(-) delete mode 100644 compose-multiplatform-material/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material/RadioButton.kt create mode 100644 compose-multiplatform-material/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material/ext/Radio.androidxCommon.kt delete mode 100644 compose-multiplatform-material/src/commonMain/kotlin/com/huanshankeji/compose/material/RadioButton.kt create mode 100644 compose-multiplatform-material/src/commonMain/kotlin/com/huanshankeji/compose/material/ext/Radio.kt delete mode 100644 compose-multiplatform-material/src/jsMain/kotlin/com/huanshankeji/compose/material/RadioButton.kt create mode 100644 compose-multiplatform-material/src/jsMain/kotlin/com/huanshankeji/compose/material/ext/Radio.js.kt diff --git a/README.md b/README.md index 32dea515..4a85af72 100644 --- a/README.md +++ b/README.md @@ -40,7 +40,6 @@ This project is prototype and there is no documentation yet. Check out [the demo - `LazyColumn`/`ScrollableList` (visually inconsistent for now) - `Text`/`MaterialText` - `TextField` -- `RadioButton` ##### `ext` components @@ -48,6 +47,8 @@ This project is prototype and there is no documentation yet. Check out [the demo - `IconButton` - `TopAppBarScaffold` - `InlineText` +- `RadioRow` +- `RadioGroupRow` #### Components in the `ext` packages diff --git a/compose-multiplatform-material/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material/RadioButton.kt b/compose-multiplatform-material/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material/RadioButton.kt deleted file mode 100644 index b93fffbd..00000000 --- a/compose-multiplatform-material/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material/RadioButton.kt +++ /dev/null @@ -1,8 +0,0 @@ -package com.huanshankeji.compose.material - -import androidx.compose.runtime.Composable -import com.huanshankeji.compose.ui.Modifier - -@Composable -actual fun RadioButton(selected: Boolean, onClick: (() -> Unit)?, modifier: Modifier, enabled: Boolean) = - androidx.compose.material.RadioButton(selected, onClick, enabled = enabled) diff --git a/compose-multiplatform-material/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material/ext/Radio.androidxCommon.kt b/compose-multiplatform-material/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material/ext/Radio.androidxCommon.kt new file mode 100644 index 00000000..e66dfde7 --- /dev/null +++ b/compose-multiplatform-material/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material/ext/Radio.androidxCommon.kt @@ -0,0 +1,24 @@ +package com.huanshankeji.compose.material.ext + +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.selection.selectable +import androidx.compose.foundation.selection.selectableGroup +import androidx.compose.material.RadioButton +import androidx.compose.material.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.semantics.Role +import com.huanshankeji.compose.ui.Modifier +import androidx.compose.ui.Modifier as PlatformModifier + +// https://developer.android.com/reference/kotlin/androidx/compose/material/package-summary#RadioButton(kotlin.Boolean,kotlin.Function0,androidx.compose.ui.Modifier,kotlin.Boolean,androidx.compose.foundation.interaction.MutableInteractionSource,androidx.compose.material.RadioButtonColors) + +@Composable +actual fun RadioRow(selected: Boolean, label: String, onClick: () -> Unit, modifier: Modifier, enabled: Boolean) = + Row(Modifier.platformModifier.selectable(selected, enabled, Role.RadioButton, onClick)) { + RadioButton(selected, null) + Text(label) + } + +@Composable +actual fun RadioGroupRow(modifier: Modifier, content: @Composable () -> Unit) = + Row(PlatformModifier.selectableGroup().then(modifier.platformModifier)) { content() } diff --git a/compose-multiplatform-material/src/commonMain/kotlin/com/huanshankeji/compose/material/RadioButton.kt b/compose-multiplatform-material/src/commonMain/kotlin/com/huanshankeji/compose/material/RadioButton.kt deleted file mode 100644 index e3255be2..00000000 --- a/compose-multiplatform-material/src/commonMain/kotlin/com/huanshankeji/compose/material/RadioButton.kt +++ /dev/null @@ -1,13 +0,0 @@ -package com.huanshankeji.compose.material - -import androidx.compose.runtime.Composable -import com.huanshankeji.compose.ui.Modifier - -// TODO colors -@Composable -expect fun RadioButton( - selected: Boolean, - onClick: (() -> Unit)?, - modifier: Modifier = Modifier, - enabled: Boolean = true -) diff --git a/compose-multiplatform-material/src/commonMain/kotlin/com/huanshankeji/compose/material/ext/Radio.kt b/compose-multiplatform-material/src/commonMain/kotlin/com/huanshankeji/compose/material/ext/Radio.kt new file mode 100644 index 00000000..4aea9033 --- /dev/null +++ b/compose-multiplatform-material/src/commonMain/kotlin/com/huanshankeji/compose/material/ext/Radio.kt @@ -0,0 +1,19 @@ +package com.huanshankeji.compose.material.ext + +import androidx.compose.runtime.Composable +import com.huanshankeji.compose.ui.Modifier + +// TODO colors +@Composable +expect fun RadioRow( + selected: Boolean, + label: String, + onClick: () -> Unit, + modifier: Modifier = Modifier, + enabled: Boolean = true +) + +@Composable +expect fun RadioGroupRow(modifier: Modifier = Modifier, content: @Composable () -> Unit) + +// TODO `RadioGroupColumn` diff --git a/compose-multiplatform-material/src/jsMain/kotlin/com/huanshankeji/compose/material/RadioButton.kt b/compose-multiplatform-material/src/jsMain/kotlin/com/huanshankeji/compose/material/RadioButton.kt deleted file mode 100644 index 7c832957..00000000 --- a/compose-multiplatform-material/src/jsMain/kotlin/com/huanshankeji/compose/material/RadioButton.kt +++ /dev/null @@ -1,11 +0,0 @@ -package com.huanshankeji.compose.material - -import androidx.compose.runtime.Composable -import com.huanshankeji.compose.ui.Modifier -import dev.petuska.kmdc.radio.MDCRadio - -@Composable -actual fun RadioButton(selected: Boolean, onClick: (() -> Unit)?, modifier: Modifier, enabled: Boolean) = - MDCRadio(selected, disabled = !enabled, attrs = { - if (onClick !== null) onClick { onClick() } - }) diff --git a/compose-multiplatform-material/src/jsMain/kotlin/com/huanshankeji/compose/material/ext/Radio.js.kt b/compose-multiplatform-material/src/jsMain/kotlin/com/huanshankeji/compose/material/ext/Radio.js.kt new file mode 100644 index 00000000..a873cfd4 --- /dev/null +++ b/compose-multiplatform-material/src/jsMain/kotlin/com/huanshankeji/compose/material/ext/Radio.js.kt @@ -0,0 +1,21 @@ +package com.huanshankeji.compose.material.ext + +import androidx.compose.runtime.Composable +import com.huanshankeji.compose.ui.Modifier +import com.varabyte.kobweb.compose.ui.toAttrs +import dev.petuska.kmdc.form.field.MDCFormField +import dev.petuska.kmdc.radio.MDCRadio + +// see: https://github.com/mpetuska/kmdc/blob/master/sandbox/src/jsMain/showcases/MDCRadio.kt + +@Composable +actual fun RadioRow(selected: Boolean, label: String, onClick: () -> Unit, modifier: Modifier, enabled: Boolean) = + MDCRadio(selected, disabled = !enabled, label = label, attrs = modifier.platformModifier.toAttrs { + onClick { onClick() } + }) + +@Composable +actual fun RadioGroupRow(modifier: Modifier, content: @Composable () -> Unit) = + MDCFormField(attrs = modifier.platformModifier.toAttrs()) { + content() + } diff --git a/demo/src/commonMain/kotlin/com/huanshankeji/compose/material/demo/App.kt b/demo/src/commonMain/kotlin/com/huanshankeji/compose/material/demo/App.kt index 081fda71..1d9afea9 100644 --- a/demo/src/commonMain/kotlin/com/huanshankeji/compose/material/demo/App.kt +++ b/demo/src/commonMain/kotlin/com/huanshankeji/compose/material/demo/App.kt @@ -11,7 +11,6 @@ import com.huanshankeji.compose.foundation.layout.Box import com.huanshankeji.compose.foundation.layout.Column import com.huanshankeji.compose.foundation.layout.Row import com.huanshankeji.compose.foundation.layout.RowScope -import com.huanshankeji.compose.foundation.onClick import com.huanshankeji.compose.foundation.text.BasicText import com.huanshankeji.compose.layout.height import com.huanshankeji.compose.layout.padding @@ -19,6 +18,8 @@ import com.huanshankeji.compose.layout.size import com.huanshankeji.compose.layout.width import com.huanshankeji.compose.material.* import com.huanshankeji.compose.material.ext.IconButton +import com.huanshankeji.compose.material.ext.RadioGroupRow +import com.huanshankeji.compose.material.ext.RadioRow import com.huanshankeji.compose.material.ext.TopAppBarScaffold import com.huanshankeji.compose.material.icons.Icons import com.huanshankeji.compose.material.icons.filled.Add @@ -122,18 +123,10 @@ fun App() { var selected by remember { mutableStateOf(RadioButtonState.A) } - // TODO `Modifier.selectableGroup()`, see https://developer.android.com/reference/kotlin/androidx/compose/material/package-summary#RadioButton(kotlin.Boolean,kotlin.Function0,androidx.compose.ui.Modifier,kotlin.Boolean,androidx.compose.foundation.interaction.MutableInteractionSource,androidx.compose.material.RadioButtonColors) - Column { + RadioGroupRow { @Composable fun RadioButtonRow(state: RadioButtonState) = - // TODO `Modifier.selectable()` - Row(Modifier.onClick { selected = state } /* TODO put in `Modifier.selectable` */) { - RadioButton(selected == state, {}) - // TODO put center vertically - Text( - text = state.toString() - ) - } + RadioRow(selected == state, state.toString(), { selected = state }) RadioButtonState.entries.forEach { RadioButtonRow(it) } } } From d89775b8c79b0e840eb22b093985297cd6806611 Mon Sep 17 00:00:00 2001 From: Shreck Ye Date: Thu, 18 Apr 2024 21:58:11 +0800 Subject: [PATCH 13/75] Add the `Checkbox` composable --- .../compose/material/Checkbox.androidxCommon.kt | 13 +++++++++++++ .../huanshankeji/compose/material/Checkbox.kt | 12 ++++++++++++ .../compose/material/Checkbox.js.kt | 17 +++++++++++++++++ 3 files changed, 42 insertions(+) create mode 100644 compose-multiplatform-material/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material/Checkbox.androidxCommon.kt create mode 100644 compose-multiplatform-material/src/commonMain/kotlin/com/huanshankeji/compose/material/Checkbox.kt create mode 100644 compose-multiplatform-material/src/jsMain/kotlin/com/huanshankeji/compose/material/Checkbox.js.kt diff --git a/compose-multiplatform-material/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material/Checkbox.androidxCommon.kt b/compose-multiplatform-material/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material/Checkbox.androidxCommon.kt new file mode 100644 index 00000000..afc32fca --- /dev/null +++ b/compose-multiplatform-material/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material/Checkbox.androidxCommon.kt @@ -0,0 +1,13 @@ +package com.huanshankeji.compose.material + +import androidx.compose.runtime.Composable +import com.huanshankeji.compose.ui.Modifier + +@Composable +actual fun Checkbox( + checked: Boolean, + onCheckedChange: ((Boolean) -> Unit)?, + modifier: Modifier, + enabled: Boolean +) = + androidx.compose.material.Checkbox(checked, onCheckedChange, modifier.platformModifier, enabled) diff --git a/compose-multiplatform-material/src/commonMain/kotlin/com/huanshankeji/compose/material/Checkbox.kt b/compose-multiplatform-material/src/commonMain/kotlin/com/huanshankeji/compose/material/Checkbox.kt new file mode 100644 index 00000000..859275a9 --- /dev/null +++ b/compose-multiplatform-material/src/commonMain/kotlin/com/huanshankeji/compose/material/Checkbox.kt @@ -0,0 +1,12 @@ +package com.huanshankeji.compose.material + +import androidx.compose.runtime.Composable +import com.huanshankeji.compose.ui.Modifier + +@Composable +expect fun Checkbox( + checked: Boolean, + onCheckedChange: ((Boolean) -> Unit)?, + modifier: Modifier = Modifier, + enabled: Boolean = true +) diff --git a/compose-multiplatform-material/src/jsMain/kotlin/com/huanshankeji/compose/material/Checkbox.js.kt b/compose-multiplatform-material/src/jsMain/kotlin/com/huanshankeji/compose/material/Checkbox.js.kt new file mode 100644 index 00000000..bf82637c --- /dev/null +++ b/compose-multiplatform-material/src/jsMain/kotlin/com/huanshankeji/compose/material/Checkbox.js.kt @@ -0,0 +1,17 @@ +package com.huanshankeji.compose.material + +import androidx.compose.runtime.Composable +import com.huanshankeji.compose.ui.Modifier +import com.varabyte.kobweb.compose.ui.toAttrs +import dev.petuska.kmdc.checkbox.MDCCheckbox + +@Composable +actual fun Checkbox( + checked: Boolean, + onCheckedChange: ((Boolean) -> Unit)?, + modifier: Modifier, + enabled: Boolean +) = + MDCCheckbox(checked, !enabled, attrs = modifier.platformModifier.toAttrs { + onCheckedChange?.let { onInput { it(!checked) } } + }) From ba62d04c21bd8ef7081d2f2b09dc595b8e2dc0a8 Mon Sep 17 00:00:00 2001 From: Shreck Ye Date: Thu, 18 Apr 2024 22:07:46 +0800 Subject: [PATCH 14/75] Test `Checkbox` in the demo and add it in README.md --- README.md | 1 + .../kotlin/com/huanshankeji/compose/material/demo/App.kt | 4 +++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 4a85af72..393f782e 100644 --- a/README.md +++ b/README.md @@ -40,6 +40,7 @@ This project is prototype and there is no documentation yet. Check out [the demo - `LazyColumn`/`ScrollableList` (visually inconsistent for now) - `Text`/`MaterialText` - `TextField` +- `Checkbox` ##### `ext` components diff --git a/demo/src/commonMain/kotlin/com/huanshankeji/compose/material/demo/App.kt b/demo/src/commonMain/kotlin/com/huanshankeji/compose/material/demo/App.kt index 1d9afea9..f3e5774d 100644 --- a/demo/src/commonMain/kotlin/com/huanshankeji/compose/material/demo/App.kt +++ b/demo/src/commonMain/kotlin/com/huanshankeji/compose/material/demo/App.kt @@ -121,7 +121,6 @@ fun App() { leadingIcon = { Icon(Icons.Default.Add, null) }, trailingIcon = { Icon(Icons.Default.Menu, null) }) - var selected by remember { mutableStateOf(RadioButtonState.A) } RadioGroupRow { @Composable @@ -129,6 +128,9 @@ fun App() { RadioRow(selected == state, state.toString(), { selected = state }) RadioButtonState.entries.forEach { RadioButtonRow(it) } } + + var checked by remember { mutableStateOf(false) } + Checkbox(checked, { checked = it }) } } } From fa2e96fbe47d96333d9f8f6b5e107dae135b52a7 Mon Sep 17 00:00:00 2001 From: Shreck Ye Date: Thu, 18 Apr 2024 23:30:46 +0800 Subject: [PATCH 15/75] Add the `Switch` Composable and test it in demo The text doesn't align well, but it seems on HTML one has to put it in `MDCForm` to make it align. --- .../compose/material/Switch.androidxCommon.kt | 15 +++++++++ .../material/ext/Switch.androidxCommon.kt | 20 ++++++++++++ .../huanshankeji/compose/material/Switch.kt | 12 +++++++ .../compose/material/ext/Switch.kt | 13 ++++++++ .../compose/material/Checkbox.js.kt | 1 + .../compose/material/Switch.js.kt | 31 +++++++++++++++++++ .../compose/material/ext/Switch.js.kt | 15 +++++++++ .../huanshankeji/compose/material/demo/App.kt | 13 ++++---- 8 files changed, 114 insertions(+), 6 deletions(-) create mode 100644 compose-multiplatform-material/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material/Switch.androidxCommon.kt create mode 100644 compose-multiplatform-material/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material/ext/Switch.androidxCommon.kt create mode 100644 compose-multiplatform-material/src/commonMain/kotlin/com/huanshankeji/compose/material/Switch.kt create mode 100644 compose-multiplatform-material/src/commonMain/kotlin/com/huanshankeji/compose/material/ext/Switch.kt create mode 100644 compose-multiplatform-material/src/jsMain/kotlin/com/huanshankeji/compose/material/Switch.js.kt create mode 100644 compose-multiplatform-material/src/jsMain/kotlin/com/huanshankeji/compose/material/ext/Switch.js.kt diff --git a/compose-multiplatform-material/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material/Switch.androidxCommon.kt b/compose-multiplatform-material/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material/Switch.androidxCommon.kt new file mode 100644 index 00000000..55098b13 --- /dev/null +++ b/compose-multiplatform-material/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material/Switch.androidxCommon.kt @@ -0,0 +1,15 @@ +package com.huanshankeji.compose.material + +import androidx.compose.runtime.Composable +import com.huanshankeji.compose.ui.Modifier + +// https://developer.android.com/develop/ui/compose/components/switch + +@Composable +actual fun Switch( + checked: Boolean, + onCheckedChange: ((Boolean) -> Unit)?, + modifier: Modifier, + enabled: Boolean +) = + androidx.compose.material.Switch(checked, onCheckedChange, modifier.platformModifier, enabled) diff --git a/compose-multiplatform-material/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material/ext/Switch.androidxCommon.kt b/compose-multiplatform-material/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material/ext/Switch.androidxCommon.kt new file mode 100644 index 00000000..c248642d --- /dev/null +++ b/compose-multiplatform-material/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material/ext/Switch.androidxCommon.kt @@ -0,0 +1,20 @@ +package com.huanshankeji.compose.material.ext + +import androidx.compose.material.Text +import androidx.compose.runtime.Composable +import com.huanshankeji.compose.foundation.layout.Row +import com.huanshankeji.compose.material.Switch +import com.huanshankeji.compose.ui.Modifier + +@Composable +actual fun SwitchWithLabel( + checked: Boolean, + onCheckedChange: ((Boolean) -> Unit)?, + label: String, + modifier: Modifier, + enabled: Boolean +) = + Row(modifier) { + Switch(checked, onCheckedChange, enabled = enabled) + Text(label) + } diff --git a/compose-multiplatform-material/src/commonMain/kotlin/com/huanshankeji/compose/material/Switch.kt b/compose-multiplatform-material/src/commonMain/kotlin/com/huanshankeji/compose/material/Switch.kt new file mode 100644 index 00000000..81075773 --- /dev/null +++ b/compose-multiplatform-material/src/commonMain/kotlin/com/huanshankeji/compose/material/Switch.kt @@ -0,0 +1,12 @@ +package com.huanshankeji.compose.material + +import androidx.compose.runtime.Composable +import com.huanshankeji.compose.ui.Modifier + +@Composable +expect fun Switch( + checked: Boolean, + onCheckedChange: ((Boolean) -> Unit)?, + modifier: Modifier = Modifier, + enabled: Boolean = true +) diff --git a/compose-multiplatform-material/src/commonMain/kotlin/com/huanshankeji/compose/material/ext/Switch.kt b/compose-multiplatform-material/src/commonMain/kotlin/com/huanshankeji/compose/material/ext/Switch.kt new file mode 100644 index 00000000..82326fc9 --- /dev/null +++ b/compose-multiplatform-material/src/commonMain/kotlin/com/huanshankeji/compose/material/ext/Switch.kt @@ -0,0 +1,13 @@ +package com.huanshankeji.compose.material.ext + +import androidx.compose.runtime.Composable +import com.huanshankeji.compose.ui.Modifier + +@Composable +expect fun SwitchWithLabel( + checked: Boolean, + onCheckedChange: ((Boolean) -> Unit)?, + label: String, + modifier: Modifier = Modifier, + enabled: Boolean = true +) diff --git a/compose-multiplatform-material/src/jsMain/kotlin/com/huanshankeji/compose/material/Checkbox.js.kt b/compose-multiplatform-material/src/jsMain/kotlin/com/huanshankeji/compose/material/Checkbox.js.kt index bf82637c..ec5f0a56 100644 --- a/compose-multiplatform-material/src/jsMain/kotlin/com/huanshankeji/compose/material/Checkbox.js.kt +++ b/compose-multiplatform-material/src/jsMain/kotlin/com/huanshankeji/compose/material/Checkbox.js.kt @@ -5,6 +5,7 @@ import com.huanshankeji.compose.ui.Modifier import com.varabyte.kobweb.compose.ui.toAttrs import dev.petuska.kmdc.checkbox.MDCCheckbox +// https://github.com/mpetuska/kmdc/blob/master/sandbox/src/jsMain/showcases/MDCCheckbox.kt @Composable actual fun Checkbox( checked: Boolean, diff --git a/compose-multiplatform-material/src/jsMain/kotlin/com/huanshankeji/compose/material/Switch.js.kt b/compose-multiplatform-material/src/jsMain/kotlin/com/huanshankeji/compose/material/Switch.js.kt new file mode 100644 index 00000000..5e737ef5 --- /dev/null +++ b/compose-multiplatform-material/src/jsMain/kotlin/com/huanshankeji/compose/material/Switch.js.kt @@ -0,0 +1,31 @@ +package com.huanshankeji.compose.material + +import androidx.compose.runtime.Composable +import com.huanshankeji.compose.ui.Modifier +import com.varabyte.kobweb.compose.ui.toAttrs +import dev.petuska.kmdc.switch.MDCSwitch +import org.jetbrains.compose.web.attributes.disabled + +// https://github.com/mpetuska/kmdc/blob/master/sandbox/src/jsMain/showcases/MDCSwitch.kt + +@Composable +internal fun CommonSwitch( + checked: Boolean, + onCheckedChange: ((Boolean) -> Unit)?, + label: String?, + modifier: Modifier, + enabled: Boolean +) = + MDCSwitch(checked, label, modifier.platformModifier.toAttrs { + if (!enabled) disabled() + onCheckedChange?.let { onClick { it(!checked) } } + }) + +@Composable +actual fun Switch( + checked: Boolean, + onCheckedChange: ((Boolean) -> Unit)?, + modifier: Modifier, + enabled: Boolean +) = + CommonSwitch(checked, onCheckedChange, null, modifier, enabled) diff --git a/compose-multiplatform-material/src/jsMain/kotlin/com/huanshankeji/compose/material/ext/Switch.js.kt b/compose-multiplatform-material/src/jsMain/kotlin/com/huanshankeji/compose/material/ext/Switch.js.kt new file mode 100644 index 00000000..75c42548 --- /dev/null +++ b/compose-multiplatform-material/src/jsMain/kotlin/com/huanshankeji/compose/material/ext/Switch.js.kt @@ -0,0 +1,15 @@ +package com.huanshankeji.compose.material.ext + +import androidx.compose.runtime.Composable +import com.huanshankeji.compose.material.CommonSwitch +import com.huanshankeji.compose.ui.Modifier + +@Composable +actual fun SwitchWithLabel( + checked: Boolean, + onCheckedChange: ((Boolean) -> Unit)?, + label: String, + modifier: Modifier, + enabled: Boolean +) = + CommonSwitch(checked, onCheckedChange, label, modifier, enabled) \ No newline at end of file diff --git a/demo/src/commonMain/kotlin/com/huanshankeji/compose/material/demo/App.kt b/demo/src/commonMain/kotlin/com/huanshankeji/compose/material/demo/App.kt index f3e5774d..0d8b4baa 100644 --- a/demo/src/commonMain/kotlin/com/huanshankeji/compose/material/demo/App.kt +++ b/demo/src/commonMain/kotlin/com/huanshankeji/compose/material/demo/App.kt @@ -17,10 +17,7 @@ import com.huanshankeji.compose.layout.padding import com.huanshankeji.compose.layout.size import com.huanshankeji.compose.layout.width import com.huanshankeji.compose.material.* -import com.huanshankeji.compose.material.ext.IconButton -import com.huanshankeji.compose.material.ext.RadioGroupRow -import com.huanshankeji.compose.material.ext.RadioRow -import com.huanshankeji.compose.material.ext.TopAppBarScaffold +import com.huanshankeji.compose.material.ext.* import com.huanshankeji.compose.material.icons.Icons import com.huanshankeji.compose.material.icons.filled.Add import com.huanshankeji.compose.material.icons.filled.Menu @@ -129,8 +126,12 @@ fun App() { RadioButtonState.entries.forEach { RadioButtonRow(it) } } - var checked by remember { mutableStateOf(false) } - Checkbox(checked, { checked = it }) + Row { + var checked by remember { mutableStateOf(false) } + Checkbox(checked, { checked = it }) + Switch(checked, { checked = it }) + SwitchWithLabel(checked, { checked = it }, "Switch") + } } } } From ca535765e2484c11d2aec365475c6763c521a940 Mon Sep 17 00:00:00 2001 From: Shreck Ye Date: Fri, 19 Apr 2024 07:23:00 +0800 Subject: [PATCH 16/75] Move text field composables to the `ext` package because `label` is a composable on `androidxCommon`, add the `OutlinedTextFiled` and `TextArea` composables, and the `singleLine` parameter --- .../material/TextField.androidxCommon.kt | 24 ------ .../material/ext/TextField.androidxCommon.kt | 68 ++++++++++++++++ .../compose/material/TextField.kt | 20 ----- .../compose/material/ext/TextField.kt | 50 ++++++++++++ .../compose/material/TextField.js.kt | 26 ------- .../compose/material/ext/TextField.js.kt | 77 +++++++++++++++++++ .../huanshankeji/compose/material/demo/App.kt | 12 ++- 7 files changed, 206 insertions(+), 71 deletions(-) delete mode 100644 compose-multiplatform-material/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material/TextField.androidxCommon.kt create mode 100644 compose-multiplatform-material/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material/ext/TextField.androidxCommon.kt delete mode 100644 compose-multiplatform-material/src/commonMain/kotlin/com/huanshankeji/compose/material/TextField.kt create mode 100644 compose-multiplatform-material/src/commonMain/kotlin/com/huanshankeji/compose/material/ext/TextField.kt delete mode 100644 compose-multiplatform-material/src/jsMain/kotlin/com/huanshankeji/compose/material/TextField.js.kt create mode 100644 compose-multiplatform-material/src/jsMain/kotlin/com/huanshankeji/compose/material/ext/TextField.js.kt diff --git a/compose-multiplatform-material/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material/TextField.androidxCommon.kt b/compose-multiplatform-material/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material/TextField.androidxCommon.kt deleted file mode 100644 index beb65401..00000000 --- a/compose-multiplatform-material/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material/TextField.androidxCommon.kt +++ /dev/null @@ -1,24 +0,0 @@ -package com.huanshankeji.compose.material - -import androidx.compose.runtime.Composable -import com.huanshankeji.compose.ui.Modifier - -@Composable -actual fun TextField( - value: String, - onValueChange: (String) -> Unit, - modifier: Modifier, - enabled: Boolean, - label: String?, - leadingIcon: @Composable (() -> Unit)?, - trailingIcon: @Composable (() -> Unit)?, -) = - androidx.compose.material.TextField( - value, - onValueChange, - modifier.platformModifier, - enabled = enabled, - label = label?.let { { Text(it) } }, - leadingIcon = leadingIcon, - trailingIcon = trailingIcon - ) diff --git a/compose-multiplatform-material/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material/ext/TextField.androidxCommon.kt b/compose-multiplatform-material/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material/ext/TextField.androidxCommon.kt new file mode 100644 index 00000000..2ac90b20 --- /dev/null +++ b/compose-multiplatform-material/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material/ext/TextField.androidxCommon.kt @@ -0,0 +1,68 @@ +package com.huanshankeji.compose.material.ext + +import androidx.compose.runtime.Composable +import com.huanshankeji.compose.material.Text +import com.huanshankeji.compose.ui.Modifier + +@Composable +actual fun TextField( + value: String, + onValueChange: (String) -> Unit, + modifier: Modifier, + enabled: Boolean, + label: String?, + leadingIcon: @Composable (() -> Unit)?, + trailingIcon: @Composable (() -> Unit)?, + singleLine: Boolean +) = + androidx.compose.material.TextField( + value, + onValueChange, + modifier.platformModifier, + enabled = enabled, + label = label?.let { { Text(it) } }, + leadingIcon = leadingIcon, + trailingIcon = trailingIcon, + singleLine = singleLine + ) + +@Composable +actual fun OutlinedTextField( + value: String, + onValueChange: (String) -> Unit, + modifier: Modifier, + enabled: Boolean, + label: String?, + leadingIcon: @Composable (() -> Unit)?, + trailingIcon: @Composable (() -> Unit)?, + singleLine: Boolean +) = + androidx.compose.material.OutlinedTextField( + value, + onValueChange, + modifier.platformModifier, + enabled = enabled, + label = label?.let { { Text(it) } }, + leadingIcon = leadingIcon, + trailingIcon = trailingIcon, + singleLine = singleLine + ) + +@Composable +actual fun TextArea( + value: String, + onValueChange: (String) -> Unit, + modifier: Modifier, + enabled: Boolean, + label: String?, + lines: Int +) = + androidx.compose.material.TextField( + value, + onValueChange, + modifier.platformModifier, + enabled = enabled, + label = label?.let { { Text(it) } }, + maxLines = lines, + minLines = lines + ) diff --git a/compose-multiplatform-material/src/commonMain/kotlin/com/huanshankeji/compose/material/TextField.kt b/compose-multiplatform-material/src/commonMain/kotlin/com/huanshankeji/compose/material/TextField.kt deleted file mode 100644 index 2d76f99b..00000000 --- a/compose-multiplatform-material/src/commonMain/kotlin/com/huanshankeji/compose/material/TextField.kt +++ /dev/null @@ -1,20 +0,0 @@ -package com.huanshankeji.compose.material - -import androidx.compose.runtime.Composable -import com.huanshankeji.compose.ui.Modifier - -@Composable -expect fun TextField( - value: String, - onValueChange: (String) -> Unit, - modifier: Modifier = Modifier, - enabled: Boolean = true, - label: String? = null, - /* - // These 2 are not the same thing. - placeholder: String? = null, - helperText: String? = null, - */ - leadingIcon: @Composable (() -> Unit)? = null, - trailingIcon: @Composable (() -> Unit)? = null -) diff --git a/compose-multiplatform-material/src/commonMain/kotlin/com/huanshankeji/compose/material/ext/TextField.kt b/compose-multiplatform-material/src/commonMain/kotlin/com/huanshankeji/compose/material/ext/TextField.kt new file mode 100644 index 00000000..1f7d69a7 --- /dev/null +++ b/compose-multiplatform-material/src/commonMain/kotlin/com/huanshankeji/compose/material/ext/TextField.kt @@ -0,0 +1,50 @@ +package com.huanshankeji.compose.material.ext + +import androidx.compose.runtime.Composable +import com.huanshankeji.compose.ui.Modifier + +/** + * @param singleLine on JS it's always single line. + */ +@Composable +expect fun TextField( + value: String, + onValueChange: (String) -> Unit, + modifier: Modifier = Modifier, + enabled: Boolean = true, + label: String? = null, + /* + // These 2 are not the same thing. + placeholder: String? = null, + helperText: String? = null, + */ + leadingIcon: @Composable (() -> Unit)? = null, + trailingIcon: @Composable (() -> Unit)? = null, + singleLine: Boolean = false +) + +// maybe put in `OutlinedTextField.kt` +/** + * @param singleLine on JS it's always single line. + */ +@Composable +expect fun OutlinedTextField( + value: String, + onValueChange: (String) -> Unit, + modifier: Modifier = Modifier, + enabled: Boolean = true, + label: String? = null, + leadingIcon: @Composable (() -> Unit)? = null, + trailingIcon: @Composable (() -> Unit)? = null, + singleLine: Boolean = false +) + +@Composable +expect fun TextArea( + value: String, + onValueChange: (String) -> Unit, + modifier: Modifier = Modifier, + enabled: Boolean = true, + label: String? = null, + lines: Int +) diff --git a/compose-multiplatform-material/src/jsMain/kotlin/com/huanshankeji/compose/material/TextField.js.kt b/compose-multiplatform-material/src/jsMain/kotlin/com/huanshankeji/compose/material/TextField.js.kt deleted file mode 100644 index 3be1a56f..00000000 --- a/compose-multiplatform-material/src/jsMain/kotlin/com/huanshankeji/compose/material/TextField.js.kt +++ /dev/null @@ -1,26 +0,0 @@ -package com.huanshankeji.compose.material - -import androidx.compose.runtime.Composable -import com.huanshankeji.compose.ui.Modifier -import com.varabyte.kobweb.compose.ui.toAttrs -import dev.petuska.kmdc.textfield.MDCTextField - -@Composable -actual fun TextField( - value: String, - onValueChange: (String) -> Unit, - modifier: Modifier, - enabled: Boolean, - label: String?, - leadingIcon: @Composable (() -> Unit)?, - trailingIcon: @Composable (() -> Unit)?, -) = - MDCTextField(value, - attrs = modifier.platformModifier.toAttrs { - onInput { onValueChange(it.value) } - }, - disabled = !enabled, - label = label, - leadingIcon = leadingIcon?.let { { it() } }, - trailingIcon = trailingIcon?.let { { it() } } - ) diff --git a/compose-multiplatform-material/src/jsMain/kotlin/com/huanshankeji/compose/material/ext/TextField.js.kt b/compose-multiplatform-material/src/jsMain/kotlin/com/huanshankeji/compose/material/ext/TextField.js.kt new file mode 100644 index 00000000..26872383 --- /dev/null +++ b/compose-multiplatform-material/src/jsMain/kotlin/com/huanshankeji/compose/material/ext/TextField.js.kt @@ -0,0 +1,77 @@ +package com.huanshankeji.compose.material.ext + +import androidx.compose.runtime.Composable +import com.huanshankeji.compose.ui.Modifier +import com.varabyte.kobweb.compose.ui.toAttrs +import dev.petuska.kmdc.textfield.MDCTextArea +import dev.petuska.kmdc.textfield.MDCTextField +import dev.petuska.kmdc.textfield.MDCTextFieldType + +@Composable +fun CommonTextField( + value: String, + type: MDCTextFieldType, + onValueChange: (String) -> Unit, + modifier: Modifier, + enabled: Boolean, + label: String?, + leadingIcon: @Composable (() -> Unit)?, + trailingIcon: @Composable (() -> Unit)? +) = + MDCTextField( + value, + type, + !enabled, + label, + leadingIcon = leadingIcon?.let { { it() } }, + trailingIcon = trailingIcon?.let { { it() } }, + attrs = modifier.platformModifier.toAttrs { + onInput { onValueChange(it.value) } + } + ) + +@Composable +actual fun TextField( + value: String, + onValueChange: (String) -> Unit, + modifier: Modifier, + enabled: Boolean, + label: String?, + leadingIcon: @Composable (() -> Unit)?, + trailingIcon: @Composable (() -> Unit)?, + singleLine: Boolean +) = + CommonTextField(value, MDCTextFieldType.Filled, onValueChange, modifier, enabled, label, leadingIcon, trailingIcon) + +@Composable +actual fun OutlinedTextField( + value: String, + onValueChange: (String) -> Unit, + modifier: Modifier, + enabled: Boolean, + label: String?, + leadingIcon: @Composable (() -> Unit)?, + trailingIcon: @Composable (() -> Unit)?, + singleLine: Boolean +) = + CommonTextField( + value, MDCTextFieldType.Outlined, onValueChange, modifier, enabled, label, leadingIcon, trailingIcon + ) + +@Composable +actual fun TextArea( + value: String, + onValueChange: (String) -> Unit, + modifier: Modifier, + enabled: Boolean, + label: String?, + lines: Int +) = + MDCTextArea( + value, + disabled = !enabled, + label = label, + rows = lines.toUInt(), + attrs = modifier.platformModifier.toAttrs { + onInput { onValueChange(it.value) } + }) diff --git a/demo/src/commonMain/kotlin/com/huanshankeji/compose/material/demo/App.kt b/demo/src/commonMain/kotlin/com/huanshankeji/compose/material/demo/App.kt index 0d8b4baa..97d4b1e0 100644 --- a/demo/src/commonMain/kotlin/com/huanshankeji/compose/material/demo/App.kt +++ b/demo/src/commonMain/kotlin/com/huanshankeji/compose/material/demo/App.kt @@ -116,7 +116,17 @@ fun App() { text, { text = it }, label = "Demo text field", leadingIcon = { Icon(Icons.Default.Add, null) }, - trailingIcon = { Icon(Icons.Default.Menu, null) }) + trailingIcon = { Icon(Icons.Default.Menu, null) }, + singleLine = true + ) + OutlinedTextField( + text, { text = it }, + label = "Demo text field", + leadingIcon = { Icon(Icons.Default.Add, null) }, + trailingIcon = { Icon(Icons.Default.Menu, null) }, + singleLine = true + ) + TextArea(text, { text = it }, label = "Demo text field", lines = 3) var selected by remember { mutableStateOf(RadioButtonState.A) } RadioGroupRow { From d74ff52d0d24c610936d87fd353c5767a7b8fa11 Mon Sep 17 00:00:00 2001 From: Shreck Ye Date: Sat, 20 Apr 2024 20:20:56 +0800 Subject: [PATCH 17/75] Try adding `Modifier.weightOrHeight` but find that Kobweb supports `Modifier.weight` too --- .../compose/foundation/ext/Column.androidxCommon.kt | 9 +++++++++ .../compose/foundation/ext/Row.androidxCommon.kt | 9 +++++++++ .../com/huanshankeji/compose/foundation/ext/Column.kt | 10 ++++++++++ .../com/huanshankeji/compose/foundation/ext/Row.kt | 10 ++++++++++ .../huanshankeji/compose/foundation/ext/Column.js.kt | 9 +++++++++ .../com/huanshankeji/compose/foundation/ext/Row.js.kt | 9 +++++++++ 6 files changed, 56 insertions(+) create mode 100644 compose-multiplatform-common/src/androidxCommonMain/kotlin/com/huanshankeji/compose/foundation/ext/Column.androidxCommon.kt create mode 100644 compose-multiplatform-common/src/androidxCommonMain/kotlin/com/huanshankeji/compose/foundation/ext/Row.androidxCommon.kt create mode 100644 compose-multiplatform-common/src/commonMain/kotlin/com/huanshankeji/compose/foundation/ext/Column.kt create mode 100644 compose-multiplatform-common/src/commonMain/kotlin/com/huanshankeji/compose/foundation/ext/Row.kt create mode 100644 compose-multiplatform-common/src/jsMain/kotlin/com/huanshankeji/compose/foundation/ext/Column.js.kt create mode 100644 compose-multiplatform-common/src/jsMain/kotlin/com/huanshankeji/compose/foundation/ext/Row.js.kt diff --git a/compose-multiplatform-common/src/androidxCommonMain/kotlin/com/huanshankeji/compose/foundation/ext/Column.androidxCommon.kt b/compose-multiplatform-common/src/androidxCommonMain/kotlin/com/huanshankeji/compose/foundation/ext/Column.androidxCommon.kt new file mode 100644 index 00000000..404f03a3 --- /dev/null +++ b/compose-multiplatform-common/src/androidxCommonMain/kotlin/com/huanshankeji/compose/foundation/ext/Column.androidxCommon.kt @@ -0,0 +1,9 @@ +package com.huanshankeji.compose.foundation.ext + +import com.huanshankeji.compose.foundation.layout.ColumnScope +import com.huanshankeji.compose.ui.Modifier + +actual fun Modifier.weightOrHeight( + columnScope: ColumnScope, weight: Float, heightPercentage: Int +): Modifier = + with(columnScope.platformValue) { platformModify { weight(weight) } } diff --git a/compose-multiplatform-common/src/androidxCommonMain/kotlin/com/huanshankeji/compose/foundation/ext/Row.androidxCommon.kt b/compose-multiplatform-common/src/androidxCommonMain/kotlin/com/huanshankeji/compose/foundation/ext/Row.androidxCommon.kt new file mode 100644 index 00000000..9e47ec4b --- /dev/null +++ b/compose-multiplatform-common/src/androidxCommonMain/kotlin/com/huanshankeji/compose/foundation/ext/Row.androidxCommon.kt @@ -0,0 +1,9 @@ +package com.huanshankeji.compose.foundation.ext + +import com.huanshankeji.compose.foundation.layout.RowScope +import com.huanshankeji.compose.ui.Modifier + +actual fun Modifier.weightOrWidth( + rowScope: RowScope, weight: Float, widthPercentage: Int +): Modifier = + TODO() diff --git a/compose-multiplatform-common/src/commonMain/kotlin/com/huanshankeji/compose/foundation/ext/Column.kt b/compose-multiplatform-common/src/commonMain/kotlin/com/huanshankeji/compose/foundation/ext/Column.kt new file mode 100644 index 00000000..ff4feb01 --- /dev/null +++ b/compose-multiplatform-common/src/commonMain/kotlin/com/huanshankeji/compose/foundation/ext/Column.kt @@ -0,0 +1,10 @@ +package com.huanshankeji.compose.foundation.ext + +import com.huanshankeji.compose.foundation.layout.ColumnScope +import com.huanshankeji.compose.ui.Modifier + +// TODO use context receivers +/** + * Delegates to `weight` on `androidx.compose` and `height` on JS. + */ +expect fun Modifier.weightOrHeight(columnScope: ColumnScope, weight: Float, heightPercentage: Int): Modifier diff --git a/compose-multiplatform-common/src/commonMain/kotlin/com/huanshankeji/compose/foundation/ext/Row.kt b/compose-multiplatform-common/src/commonMain/kotlin/com/huanshankeji/compose/foundation/ext/Row.kt new file mode 100644 index 00000000..757090bf --- /dev/null +++ b/compose-multiplatform-common/src/commonMain/kotlin/com/huanshankeji/compose/foundation/ext/Row.kt @@ -0,0 +1,10 @@ +package com.huanshankeji.compose.foundation.ext + +import com.huanshankeji.compose.foundation.layout.RowScope +import com.huanshankeji.compose.ui.Modifier + +// TODO use context receivers +/** + * Delegates to `weight` on `androidx.compose` and `width` on JS. + */ +expect fun Modifier.weightOrWidth(rowScope: RowScope, weight: Float, widthPercentage: Int): Modifier diff --git a/compose-multiplatform-common/src/jsMain/kotlin/com/huanshankeji/compose/foundation/ext/Column.js.kt b/compose-multiplatform-common/src/jsMain/kotlin/com/huanshankeji/compose/foundation/ext/Column.js.kt new file mode 100644 index 00000000..404f03a3 --- /dev/null +++ b/compose-multiplatform-common/src/jsMain/kotlin/com/huanshankeji/compose/foundation/ext/Column.js.kt @@ -0,0 +1,9 @@ +package com.huanshankeji.compose.foundation.ext + +import com.huanshankeji.compose.foundation.layout.ColumnScope +import com.huanshankeji.compose.ui.Modifier + +actual fun Modifier.weightOrHeight( + columnScope: ColumnScope, weight: Float, heightPercentage: Int +): Modifier = + with(columnScope.platformValue) { platformModify { weight(weight) } } diff --git a/compose-multiplatform-common/src/jsMain/kotlin/com/huanshankeji/compose/foundation/ext/Row.js.kt b/compose-multiplatform-common/src/jsMain/kotlin/com/huanshankeji/compose/foundation/ext/Row.js.kt new file mode 100644 index 00000000..9e47ec4b --- /dev/null +++ b/compose-multiplatform-common/src/jsMain/kotlin/com/huanshankeji/compose/foundation/ext/Row.js.kt @@ -0,0 +1,9 @@ +package com.huanshankeji.compose.foundation.ext + +import com.huanshankeji.compose.foundation.layout.RowScope +import com.huanshankeji.compose.ui.Modifier + +actual fun Modifier.weightOrWidth( + rowScope: RowScope, weight: Float, widthPercentage: Int +): Modifier = + TODO() From 30cef357d78bdba12a7366510b7221abb57276c8 Mon Sep 17 00:00:00 2001 From: Shreck Ye Date: Sun, 21 Apr 2024 09:07:32 +0800 Subject: [PATCH 18/75] Add `Modifier.weight` in `ColumnScope` and `RowScope` and use it in the demo, and remove the ones added in the previous commit On JS `Modifier.weight` doesn't work perfectly: a component doesn't occupy its exact portion of the size, but shrinks to the content size. --- .../foundation/ext/Column.androidxCommon.kt | 9 -- .../foundation/ext/Row.androidxCommon.kt | 9 -- .../layout/Column.androidxCommon.kt | 8 + .../foundation/layout/Row.androidxCommon.kt | 7 + .../compose/foundation/ext/Column.kt | 10 -- .../compose/foundation/ext/Row.kt | 10 -- .../compose/foundation/layout/Column.kt | 7 + .../compose/foundation/layout/Row.kt | 7 + .../compose/foundation/ext/Column.js.kt | 9 -- .../compose/foundation/ext/Row.js.kt | 9 -- .../compose/foundation/layout/Column.js.kt | 8 + .../compose/foundation/layout/Row.js.kt | 8 + .../huanshankeji/compose/material/demo/App.kt | 150 ++---------------- .../compose/material/demo/Material2.kt | 149 +++++++++++++++++ .../compose/material/demo/Material3.kt | 8 + 15 files changed, 213 insertions(+), 195 deletions(-) delete mode 100644 compose-multiplatform-common/src/androidxCommonMain/kotlin/com/huanshankeji/compose/foundation/ext/Column.androidxCommon.kt delete mode 100644 compose-multiplatform-common/src/androidxCommonMain/kotlin/com/huanshankeji/compose/foundation/ext/Row.androidxCommon.kt delete mode 100644 compose-multiplatform-common/src/commonMain/kotlin/com/huanshankeji/compose/foundation/ext/Column.kt delete mode 100644 compose-multiplatform-common/src/commonMain/kotlin/com/huanshankeji/compose/foundation/ext/Row.kt delete mode 100644 compose-multiplatform-common/src/jsMain/kotlin/com/huanshankeji/compose/foundation/ext/Column.js.kt delete mode 100644 compose-multiplatform-common/src/jsMain/kotlin/com/huanshankeji/compose/foundation/ext/Row.js.kt create mode 100644 demo/src/commonMain/kotlin/com/huanshankeji/compose/material/demo/Material2.kt create mode 100644 demo/src/commonMain/kotlin/com/huanshankeji/compose/material/demo/Material3.kt diff --git a/compose-multiplatform-common/src/androidxCommonMain/kotlin/com/huanshankeji/compose/foundation/ext/Column.androidxCommon.kt b/compose-multiplatform-common/src/androidxCommonMain/kotlin/com/huanshankeji/compose/foundation/ext/Column.androidxCommon.kt deleted file mode 100644 index 404f03a3..00000000 --- a/compose-multiplatform-common/src/androidxCommonMain/kotlin/com/huanshankeji/compose/foundation/ext/Column.androidxCommon.kt +++ /dev/null @@ -1,9 +0,0 @@ -package com.huanshankeji.compose.foundation.ext - -import com.huanshankeji.compose.foundation.layout.ColumnScope -import com.huanshankeji.compose.ui.Modifier - -actual fun Modifier.weightOrHeight( - columnScope: ColumnScope, weight: Float, heightPercentage: Int -): Modifier = - with(columnScope.platformValue) { platformModify { weight(weight) } } diff --git a/compose-multiplatform-common/src/androidxCommonMain/kotlin/com/huanshankeji/compose/foundation/ext/Row.androidxCommon.kt b/compose-multiplatform-common/src/androidxCommonMain/kotlin/com/huanshankeji/compose/foundation/ext/Row.androidxCommon.kt deleted file mode 100644 index 9e47ec4b..00000000 --- a/compose-multiplatform-common/src/androidxCommonMain/kotlin/com/huanshankeji/compose/foundation/ext/Row.androidxCommon.kt +++ /dev/null @@ -1,9 +0,0 @@ -package com.huanshankeji.compose.foundation.ext - -import com.huanshankeji.compose.foundation.layout.RowScope -import com.huanshankeji.compose.ui.Modifier - -actual fun Modifier.weightOrWidth( - rowScope: RowScope, weight: Float, widthPercentage: Int -): Modifier = - TODO() diff --git a/compose-multiplatform-common/src/androidxCommonMain/kotlin/com/huanshankeji/compose/foundation/layout/Column.androidxCommon.kt b/compose-multiplatform-common/src/androidxCommonMain/kotlin/com/huanshankeji/compose/foundation/layout/Column.androidxCommon.kt index 0e4c6e61..278109e4 100644 --- a/compose-multiplatform-common/src/androidxCommonMain/kotlin/com/huanshankeji/compose/foundation/layout/Column.androidxCommon.kt +++ b/compose-multiplatform-common/src/androidxCommonMain/kotlin/com/huanshankeji/compose/foundation/layout/Column.androidxCommon.kt @@ -1,5 +1,6 @@ package com.huanshankeji.compose.foundation.layout +import androidx.annotation.FloatRange import androidx.compose.runtime.Composable import androidx.compose.runtime.Stable import com.huanshankeji.compose.ui.Alignment @@ -27,6 +28,13 @@ actual interface ColumnScope { @JvmInline value class Impl(override val platformValue: PlatformColumnScope) : ColumnScope + @Stable + actual fun Modifier.weight( + @FloatRange(from = 0.0, fromInclusive = false) + weight: Float + ): Modifier = + with(platformValue) { platformModify { weight(weight) } } + @Stable actual fun Modifier.align(alignment: Alignment.Horizontal): Modifier = with(platformValue) { platformModify { align(alignment.platformHorizontal) } } diff --git a/compose-multiplatform-common/src/androidxCommonMain/kotlin/com/huanshankeji/compose/foundation/layout/Row.androidxCommon.kt b/compose-multiplatform-common/src/androidxCommonMain/kotlin/com/huanshankeji/compose/foundation/layout/Row.androidxCommon.kt index b26d0074..e0c5a769 100644 --- a/compose-multiplatform-common/src/androidxCommonMain/kotlin/com/huanshankeji/compose/foundation/layout/Row.androidxCommon.kt +++ b/compose-multiplatform-common/src/androidxCommonMain/kotlin/com/huanshankeji/compose/foundation/layout/Row.androidxCommon.kt @@ -1,5 +1,6 @@ package com.huanshankeji.compose.foundation.layout +import androidx.annotation.FloatRange import androidx.compose.runtime.Composable import androidx.compose.runtime.Stable import com.huanshankeji.compose.ui.Alignment @@ -27,6 +28,12 @@ actual interface RowScope { @JvmInline value class Impl(override val platformValue: PlatformRowScope) : RowScope + actual fun Modifier.weight( + @FloatRange(from = 0.0, fromInclusive = false) + weight: Float + ): Modifier = + with(platformValue) { platformModify { weight(weight) } } + @Stable actual fun Modifier.align(alignment: Alignment.Vertical): Modifier = with(platformValue) { platformModify { align(alignment.platformHorizontal) } } diff --git a/compose-multiplatform-common/src/commonMain/kotlin/com/huanshankeji/compose/foundation/ext/Column.kt b/compose-multiplatform-common/src/commonMain/kotlin/com/huanshankeji/compose/foundation/ext/Column.kt deleted file mode 100644 index ff4feb01..00000000 --- a/compose-multiplatform-common/src/commonMain/kotlin/com/huanshankeji/compose/foundation/ext/Column.kt +++ /dev/null @@ -1,10 +0,0 @@ -package com.huanshankeji.compose.foundation.ext - -import com.huanshankeji.compose.foundation.layout.ColumnScope -import com.huanshankeji.compose.ui.Modifier - -// TODO use context receivers -/** - * Delegates to `weight` on `androidx.compose` and `height` on JS. - */ -expect fun Modifier.weightOrHeight(columnScope: ColumnScope, weight: Float, heightPercentage: Int): Modifier diff --git a/compose-multiplatform-common/src/commonMain/kotlin/com/huanshankeji/compose/foundation/ext/Row.kt b/compose-multiplatform-common/src/commonMain/kotlin/com/huanshankeji/compose/foundation/ext/Row.kt deleted file mode 100644 index 757090bf..00000000 --- a/compose-multiplatform-common/src/commonMain/kotlin/com/huanshankeji/compose/foundation/ext/Row.kt +++ /dev/null @@ -1,10 +0,0 @@ -package com.huanshankeji.compose.foundation.ext - -import com.huanshankeji.compose.foundation.layout.RowScope -import com.huanshankeji.compose.ui.Modifier - -// TODO use context receivers -/** - * Delegates to `weight` on `androidx.compose` and `width` on JS. - */ -expect fun Modifier.weightOrWidth(rowScope: RowScope, weight: Float, widthPercentage: Int): Modifier diff --git a/compose-multiplatform-common/src/commonMain/kotlin/com/huanshankeji/compose/foundation/layout/Column.kt b/compose-multiplatform-common/src/commonMain/kotlin/com/huanshankeji/compose/foundation/layout/Column.kt index 5017ea6f..50ca8bca 100644 --- a/compose-multiplatform-common/src/commonMain/kotlin/com/huanshankeji/compose/foundation/layout/Column.kt +++ b/compose-multiplatform-common/src/commonMain/kotlin/com/huanshankeji/compose/foundation/layout/Column.kt @@ -1,5 +1,6 @@ package com.huanshankeji.compose.foundation.layout +import androidx.annotation.FloatRange import androidx.compose.runtime.Composable import androidx.compose.runtime.Stable import com.huanshankeji.compose.ui.Alignment @@ -15,6 +16,12 @@ expect fun Column( //@LayoutScopeMarker expect interface ColumnScope { + @Stable + open fun Modifier.weight( + @FloatRange(from = 0.0, fromInclusive = false) + weight: Float + ): Modifier + @Stable open fun Modifier.align(alignment: Alignment.Horizontal): Modifier } diff --git a/compose-multiplatform-common/src/commonMain/kotlin/com/huanshankeji/compose/foundation/layout/Row.kt b/compose-multiplatform-common/src/commonMain/kotlin/com/huanshankeji/compose/foundation/layout/Row.kt index 4accffe4..1608d327 100644 --- a/compose-multiplatform-common/src/commonMain/kotlin/com/huanshankeji/compose/foundation/layout/Row.kt +++ b/compose-multiplatform-common/src/commonMain/kotlin/com/huanshankeji/compose/foundation/layout/Row.kt @@ -1,5 +1,6 @@ package com.huanshankeji.compose.foundation.layout +import androidx.annotation.FloatRange import androidx.compose.runtime.Composable import androidx.compose.runtime.Stable import com.huanshankeji.compose.ui.Alignment @@ -15,6 +16,12 @@ expect fun Row( //@LayoutScopeMarker expect interface RowScope { + @Stable + open fun Modifier.weight( + @FloatRange(from = 0.0, fromInclusive = false) + weight: Float + ): Modifier + @Stable open fun Modifier.align(alignment: Alignment.Vertical): Modifier } diff --git a/compose-multiplatform-common/src/jsMain/kotlin/com/huanshankeji/compose/foundation/ext/Column.js.kt b/compose-multiplatform-common/src/jsMain/kotlin/com/huanshankeji/compose/foundation/ext/Column.js.kt deleted file mode 100644 index 404f03a3..00000000 --- a/compose-multiplatform-common/src/jsMain/kotlin/com/huanshankeji/compose/foundation/ext/Column.js.kt +++ /dev/null @@ -1,9 +0,0 @@ -package com.huanshankeji.compose.foundation.ext - -import com.huanshankeji.compose.foundation.layout.ColumnScope -import com.huanshankeji.compose.ui.Modifier - -actual fun Modifier.weightOrHeight( - columnScope: ColumnScope, weight: Float, heightPercentage: Int -): Modifier = - with(columnScope.platformValue) { platformModify { weight(weight) } } diff --git a/compose-multiplatform-common/src/jsMain/kotlin/com/huanshankeji/compose/foundation/ext/Row.js.kt b/compose-multiplatform-common/src/jsMain/kotlin/com/huanshankeji/compose/foundation/ext/Row.js.kt deleted file mode 100644 index 9e47ec4b..00000000 --- a/compose-multiplatform-common/src/jsMain/kotlin/com/huanshankeji/compose/foundation/ext/Row.js.kt +++ /dev/null @@ -1,9 +0,0 @@ -package com.huanshankeji.compose.foundation.ext - -import com.huanshankeji.compose.foundation.layout.RowScope -import com.huanshankeji.compose.ui.Modifier - -actual fun Modifier.weightOrWidth( - rowScope: RowScope, weight: Float, widthPercentage: Int -): Modifier = - TODO() diff --git a/compose-multiplatform-common/src/jsMain/kotlin/com/huanshankeji/compose/foundation/layout/Column.js.kt b/compose-multiplatform-common/src/jsMain/kotlin/com/huanshankeji/compose/foundation/layout/Column.js.kt index 4a0d132f..76ee7a8d 100644 --- a/compose-multiplatform-common/src/jsMain/kotlin/com/huanshankeji/compose/foundation/layout/Column.js.kt +++ b/compose-multiplatform-common/src/jsMain/kotlin/com/huanshankeji/compose/foundation/layout/Column.js.kt @@ -1,5 +1,6 @@ package com.huanshankeji.compose.foundation.layout +import androidx.annotation.FloatRange import androidx.compose.runtime.Composable import androidx.compose.runtime.Stable import com.huanshankeji.compose.ui.Alignment @@ -34,6 +35,13 @@ actual interface ColumnScope { value class Impl(override val platformValue: PlatformColumnScope) : ColumnScope + @Stable + actual fun Modifier.weight( + @FloatRange(from = 0.0, fromInclusive = false) + weight: Float + ): Modifier = + with(platformValue) { platformModify { weight(weight) } } + @Stable actual fun Modifier.align(alignment: Alignment.Horizontal): Modifier = with(platformValue) { platformModify { align(alignment.platformValue) } } diff --git a/compose-multiplatform-common/src/jsMain/kotlin/com/huanshankeji/compose/foundation/layout/Row.js.kt b/compose-multiplatform-common/src/jsMain/kotlin/com/huanshankeji/compose/foundation/layout/Row.js.kt index e628cfa7..88f83c49 100644 --- a/compose-multiplatform-common/src/jsMain/kotlin/com/huanshankeji/compose/foundation/layout/Row.js.kt +++ b/compose-multiplatform-common/src/jsMain/kotlin/com/huanshankeji/compose/foundation/layout/Row.js.kt @@ -1,5 +1,6 @@ package com.huanshankeji.compose.foundation.layout +import androidx.annotation.FloatRange import androidx.compose.runtime.Composable import androidx.compose.runtime.Stable import com.huanshankeji.compose.ui.Alignment @@ -35,6 +36,13 @@ actual interface RowScope { value class Impl(override val platformValue: PlatformRowScope) : RowScope + @Stable + actual fun Modifier.weight( + @FloatRange(from = 0.0, fromInclusive = false) + weight: Float + ): Modifier = + with(platformValue) { platformModify { weight(weight) } } + @Stable actual fun Modifier.align(alignment: Alignment.Vertical): Modifier = with(platformValue) { platformModify { align(alignment.platformValue) } } diff --git a/demo/src/commonMain/kotlin/com/huanshankeji/compose/material/demo/App.kt b/demo/src/commonMain/kotlin/com/huanshankeji/compose/material/demo/App.kt index fc1d4e39..83083362 100644 --- a/demo/src/commonMain/kotlin/com/huanshankeji/compose/material/demo/App.kt +++ b/demo/src/commonMain/kotlin/com/huanshankeji/compose/material/demo/App.kt @@ -1,155 +1,27 @@ package com.huanshankeji.compose.material.demo -import androidx.compose.runtime.* -import androidx.compose.ui.unit.dp -import com.huanshankeji.compose.foundation.background -import com.huanshankeji.compose.foundation.border -import com.huanshankeji.compose.foundation.ext.outerBorder -import com.huanshankeji.compose.foundation.ext.roundedCornerBackgroundAndOuterBorder -import com.huanshankeji.compose.foundation.ext.roundedCornerOuterBorder +import androidx.compose.runtime.Composable import com.huanshankeji.compose.foundation.layout.Box import com.huanshankeji.compose.foundation.layout.Column import com.huanshankeji.compose.foundation.layout.Row -import com.huanshankeji.compose.foundation.layout.RowScope import com.huanshankeji.compose.foundation.text.BasicText -import com.huanshankeji.compose.layout.height -import com.huanshankeji.compose.layout.padding -import com.huanshankeji.compose.layout.size -import com.huanshankeji.compose.layout.width -import com.huanshankeji.compose.material.* -import com.huanshankeji.compose.material.ext.* -import com.huanshankeji.compose.material.icons.Icons -import com.huanshankeji.compose.material.icons.filled.Add -import com.huanshankeji.compose.material.icons.filled.Menu -import com.huanshankeji.compose.material.icons.filled.Search -import com.huanshankeji.compose.material.lazy.ext.LazyColumn import com.huanshankeji.compose.ui.Modifier -import com.huanshankeji.compose.ui.graphics.Color -import com.huanshankeji.compose.material.ext.Button as ExtButton -import com.huanshankeji.compose.material3.Button as M3Button -import com.huanshankeji.compose.material3.ext.Button as M3ExtButton -private enum class RadioButtonState { +internal enum class RadioButtonState { A, B, C } @Composable fun App() { - TopAppBarScaffold({ - Text("Compose Multiplatform Material demo") - }, navigationIcon = { - MaterialIconNavButton({}, Icons.Default.Menu, "menu") - }, actions = { - MaterialIconActionButton({}, Icons.Default.Search, "search") - }) { - Card(Modifier.padding(16.dp).height(800.dp).width(400.dp)) { - Column(Modifier.padding(16.dp)) { - BasicText("basic text 1") - BasicText("basic text 2") - Text("Material text") - - var count by remember { mutableStateOf(0) } - val onClick: () -> Unit = { count++ } - - val buttonContent: @Composable () -> Unit = { - Text(count.toString()) // TODO use `com.huanshankeji.compose.material(3).ext.InlineText` - } - val rowScopeButtonContent: @Composable RowScope.() -> Unit = { buttonContent()} - - Row { - Button(onClick, content = rowScopeButtonContent) - OutlinedButton(onClick, content = rowScopeButtonContent) - TextButton(onClick, content = rowScopeButtonContent) - ExtButton(onClick) { - Label(count.toString()) - } - IconButton(onClick, icon = Icons.Default.Add, contentDescription = "increment count") - } - Row { - M3Button(onClick, content = rowScopeButtonContent) - M3ExtButton(onClick) { buttonContent() } - } - - Box(Modifier.padding(16.dp)) { - LazyColumn(Modifier.height(100.dp)) { - item { - Text("Ungrouped item") - } - items(count) { - Text("Ungrouped item $it/$count") - } - group(headerContent = { - Text("Group title") - }) { - item { - Text("Grouped item") - } - items(count) { - Text("Grouped item $it/$count") - } - } - } - } - - @Composable - fun ColorBox(color: Color) = - Box(Modifier.padding(8.dp).background(color).size(40.dp)) - - val halfGreen = Color(0, 0x80, 0x00) - - Row(Modifier.roundedCornerBackgroundAndOuterBorder(4.dp, Color.Blue, 16.dp, halfGreen)) { - ColorBox(Color.Red) - ColorBox(Color(0xFF, 0, 0)) - ColorBox(Color(0xFF, 0, 0, 0x80)) - ColorBox(Color(1f, 0f, 0f, 0.5f)) - } - - Row { - @Composable - fun NestedColorBox(modifier: Modifier) = - Box(modifier.background(halfGreen)) { ColorBox(Color.Red) } - - NestedColorBox(Modifier.border(4.dp, Color.Blue)) - NestedColorBox(Modifier.outerBorder(4.dp, Color.Blue)) - NestedColorBox(Modifier.roundedCornerOuterBorder(4.dp, Color.Blue, 16.dp)) - NestedColorBox(Modifier.roundedCornerOuterBorder(1.dp, Color.Blue, 16.dp)) - val transparentBlue = Color(0, 0, 0x80, 0x80) - Box(Modifier.roundedCornerBackgroundAndOuterBorder(2.dp, transparentBlue, 16.dp, halfGreen)) { - ColorBox(Color.Red) - } - } - - var text by remember { mutableStateOf("") } - TextField( - text, { text = it }, - label = "Demo text field", - leadingIcon = { Icon(Icons.Default.Add, null) }, - trailingIcon = { Icon(Icons.Default.Menu, null) }, - singleLine = true - ) - OutlinedTextField( - text, { text = it }, - label = "Demo text field", - leadingIcon = { Icon(Icons.Default.Add, null) }, - trailingIcon = { Icon(Icons.Default.Menu, null) }, - singleLine = true - ) - TextArea(text, { text = it }, label = "Demo text field", lines = 3) - - var selected by remember { mutableStateOf(RadioButtonState.A) } - RadioGroupRow { - @Composable - fun RadioButtonRow(state: RadioButtonState) = - RadioRow(selected == state, state.toString(), { selected = state }) - RadioButtonState.entries.forEach { RadioButtonRow(it) } - } - - Row { - var checked by remember { mutableStateOf(false) } - Checkbox(checked, { checked = it }) - Switch(checked, { checked = it }) - SwitchWithLabel(checked, { checked = it }, "Switch") - } + Column { + BasicText("basic text 1") + BasicText("basic text 2") + Row { + Box(Modifier.weight(1f)) { + Material2() + } + Box(Modifier.weight(1f)) { + Material3() } } } diff --git a/demo/src/commonMain/kotlin/com/huanshankeji/compose/material/demo/Material2.kt b/demo/src/commonMain/kotlin/com/huanshankeji/compose/material/demo/Material2.kt new file mode 100644 index 00000000..76c2407c --- /dev/null +++ b/demo/src/commonMain/kotlin/com/huanshankeji/compose/material/demo/Material2.kt @@ -0,0 +1,149 @@ +package com.huanshankeji.compose.material.demo + +import androidx.compose.runtime.* +import androidx.compose.ui.unit.dp +import com.huanshankeji.compose.foundation.background +import com.huanshankeji.compose.foundation.border +import com.huanshankeji.compose.foundation.ext.outerBorder +import com.huanshankeji.compose.foundation.ext.roundedCornerBackgroundAndOuterBorder +import com.huanshankeji.compose.foundation.ext.roundedCornerOuterBorder +import com.huanshankeji.compose.foundation.layout.Box +import com.huanshankeji.compose.foundation.layout.Column +import com.huanshankeji.compose.foundation.layout.Row +import com.huanshankeji.compose.foundation.layout.RowScope +import com.huanshankeji.compose.layout.height +import com.huanshankeji.compose.layout.padding +import com.huanshankeji.compose.layout.size +import com.huanshankeji.compose.layout.width +import com.huanshankeji.compose.material.* +import com.huanshankeji.compose.material.ext.* +import com.huanshankeji.compose.material.icons.Icons +import com.huanshankeji.compose.material.icons.filled.Add +import com.huanshankeji.compose.material.icons.filled.Menu +import com.huanshankeji.compose.material.icons.filled.Search +import com.huanshankeji.compose.material.lazy.ext.LazyColumn +import com.huanshankeji.compose.ui.Modifier +import com.huanshankeji.compose.ui.graphics.Color +import com.huanshankeji.compose.material.ext.Button as ExtButton +import com.huanshankeji.compose.material3.Button as M3Button +import com.huanshankeji.compose.material3.ext.Button as M3ExtButton + +@Composable +fun Material2() { + TopAppBarScaffold({ + Text("Compose Multiplatform Material demo") + }, navigationIcon = { + MaterialIconNavButton({}, Icons.Default.Menu, "menu") + }, actions = { + MaterialIconActionButton({}, Icons.Default.Search, "search") + }) { + Card(Modifier.padding(16.dp).height(800.dp).width(400.dp)) { + Column(Modifier.padding(16.dp)) { + Text("Material text") + + var count by remember { mutableStateOf(0) } + val onClick: () -> Unit = { count++ } + + val buttonContent: @Composable () -> Unit = { + Text(count.toString()) // TODO use `com.huanshankeji.compose.material(3).ext.InlineText` + } + val rowScopeButtonContent: @Composable RowScope.() -> Unit = { buttonContent() } + + Row { + Button(onClick, content = rowScopeButtonContent) + OutlinedButton(onClick, content = rowScopeButtonContent) + TextButton(onClick, content = rowScopeButtonContent) + ExtButton(onClick) { + Label(count.toString()) + } + IconButton(onClick, icon = Icons.Default.Add, contentDescription = "increment count") + } + Row { + M3Button(onClick, content = rowScopeButtonContent) + M3ExtButton(onClick) { buttonContent() } + } + + Box(Modifier.padding(16.dp)) { + LazyColumn(Modifier.height(100.dp)) { + item { + Text("Ungrouped item") + } + items(count) { + Text("Ungrouped item $it/$count") + } + group(headerContent = { + Text("Group title") + }) { + item { + Text("Grouped item") + } + items(count) { + Text("Grouped item $it/$count") + } + } + } + } + + @Composable + fun ColorBox(color: Color) = + Box(Modifier.padding(8.dp).background(color).size(40.dp)) + + val halfGreen = Color(0, 0x80, 0x00) + + Row(Modifier.roundedCornerBackgroundAndOuterBorder(4.dp, Color.Blue, 16.dp, halfGreen)) { + ColorBox(Color.Red) + ColorBox(Color(0xFF, 0, 0)) + ColorBox(Color(0xFF, 0, 0, 0x80)) + ColorBox(Color(1f, 0f, 0f, 0.5f)) + } + + Row { + @Composable + fun NestedColorBox(modifier: Modifier) = + Box(modifier.background(halfGreen)) { ColorBox(Color.Red) } + + NestedColorBox(Modifier.border(4.dp, Color.Blue)) + NestedColorBox(Modifier.outerBorder(4.dp, Color.Blue)) + NestedColorBox(Modifier.roundedCornerOuterBorder(4.dp, Color.Blue, 16.dp)) + NestedColorBox(Modifier.roundedCornerOuterBorder(1.dp, Color.Blue, 16.dp)) + val transparentBlue = Color(0, 0, 0x80, 0x80) + Box(Modifier.roundedCornerBackgroundAndOuterBorder(2.dp, transparentBlue, 16.dp, halfGreen)) { + ColorBox(Color.Red) + } + } + + var text by remember { mutableStateOf("") } + TextField( + text, { text = it }, + label = "Demo text field", + leadingIcon = { Icon(Icons.Default.Add, null) }, + trailingIcon = { Icon(Icons.Default.Menu, null) }, + singleLine = true + ) + OutlinedTextField( + text, { text = it }, + label = "Demo text field", + leadingIcon = { Icon(Icons.Default.Add, null) }, + trailingIcon = { Icon(Icons.Default.Menu, null) }, + singleLine = true + ) + TextArea(text, { text = it }, label = "Demo text field", lines = 3) + + var selected by remember { mutableStateOf(RadioButtonState.A) } + RadioGroupRow { + @Composable + fun RadioButtonRow(state: RadioButtonState) = + RadioRow(selected == state, state.toString(), { selected = state }) + RadioButtonState.entries.forEach { RadioButtonRow(it) } + } + + Row { + var checked by remember { mutableStateOf(false) } + Checkbox(checked, { checked = it }) + Switch(checked, { checked = it }) + SwitchWithLabel(checked, { checked = it }, "Switch") + } + } + } + } +} diff --git a/demo/src/commonMain/kotlin/com/huanshankeji/compose/material/demo/Material3.kt b/demo/src/commonMain/kotlin/com/huanshankeji/compose/material/demo/Material3.kt new file mode 100644 index 00000000..c70f71eb --- /dev/null +++ b/demo/src/commonMain/kotlin/com/huanshankeji/compose/material/demo/Material3.kt @@ -0,0 +1,8 @@ +package com.huanshankeji.compose.material.demo + +import androidx.compose.runtime.Composable + +@Composable +fun Material3() { + Material2() // TODO +} \ No newline at end of file From 37573fb8db829053a51272cad108db0c41905b85 Mon Sep 17 00:00:00 2001 From: Shreck Ye Date: Sun, 21 Apr 2024 09:14:26 +0800 Subject: [PATCH 19/75] The issue mentioned in the previous commit can't be resolved with `fillMaxWidth` From c5cc80f07f93df2627905b612642061da83f488c Mon Sep 17 00:00:00 2001 From: Shreck Ye Date: Sun, 21 Apr 2024 10:39:24 +0800 Subject: [PATCH 20/75] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 393f782e..da749ebb 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# Compose Multiplatform Material wrappers for `androidx.compose.material` and Compose HTML +# Compose Multiplatform common extensions and Material wrappers for `androidx.compose.material` and Compose HTML [![Maven Central](https://img.shields.io/maven-central/v/com.huanshankeji/compose-multiplatform-material)](https://search.maven.org/search?q=g:com.huanshankeji%20AND%20a:compose-multiplatform-*) ![Kotlin version](https://kotlin-version.aws.icerock.dev/kotlin-version?group=com.huanshankeji&name=compose-multiplatform-material) From 22c091fa26712e5a6e9fc258678900fc1ff835bd Mon Sep 17 00:00:00 2001 From: Shreck Ye Date: Sun, 21 Apr 2024 10:45:06 +0800 Subject: [PATCH 21/75] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 33eb769d..86dc470f 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ [![Maven Central](https://img.shields.io/maven-central/v/com.huanshankeji/compose-multiplatform-material)](https://search.maven.org/search?q=g:com.huanshankeji%20AND%20a:compose-multiplatform-*) ![Kotlin version](https://kotlin-version.aws.icerock.dev/kotlin-version?group=com.huanshankeji&name=compose-multiplatform-material) -Some simple unified Compose Multiplatform wrappers of common components, layouts, and Material Design components for `androidx.compose.material` (officially supported on Android, desktop (JVM), iOS, web (Kotlin/Wasm)) and Compose HTML (mainly based on [Kobweb Silk](https://github.com/varabyte/kobweb?tab=readme-ov-file#silk) and [KMDC](https://github.com/mpetuska/kmdc)) +Some simple unified Compose Multiplatform wrappers of common components, layouts, and Material Design components for `androidx.compose.material` (officially supported on Android, desktop (JVM), iOS, web (Kotlin/Wasm)) and Compose HTML (mainly based on [Kobweb Silk](https://github.com/varabyte/kobweb?tab=readme-ov-file#silk) [Compose](https://github.com/varabyte/kobweb/tree/main/frontend/kobweb-compose), [KMDC](https://github.com/mpetuska/kmdc), and [Compose HTML Material](https://github.com/huanshankeji/compose-html-material) (which is then based on [Material Web](https://github.com/material-components/material-web))) From 581b9a9300336ae2ac726e9e3bd6733d87e044b0 Mon Sep 17 00:00:00 2001 From: Shreck Ye Date: Sun, 21 Apr 2024 15:11:33 +0800 Subject: [PATCH 22/75] Add the `wrapContent...` modifiers --- .../compose/layout/Size.androidxCommon.kt | 13 +++++++++++++ .../com/huanshankeji/compose/layout/Size.kt | 10 ++++++++++ .../com/huanshankeji/compose/layout/Size.js.kt | 17 +++++++++++++++++ .../kobweb/compose/ui/modifiers/Size.kt | 1 + 4 files changed, 41 insertions(+) diff --git a/compose-multiplatform-common/src/androidxCommonMain/kotlin/com/huanshankeji/compose/layout/Size.androidxCommon.kt b/compose-multiplatform-common/src/androidxCommonMain/kotlin/com/huanshankeji/compose/layout/Size.androidxCommon.kt index 2331ed46..58298a04 100644 --- a/compose-multiplatform-common/src/androidxCommonMain/kotlin/com/huanshankeji/compose/layout/Size.androidxCommon.kt +++ b/compose-multiplatform-common/src/androidxCommonMain/kotlin/com/huanshankeji/compose/layout/Size.androidxCommon.kt @@ -44,5 +44,18 @@ actual fun Modifier.fillMaxWidth(@FloatRange(from = 0.0, to = 1.0) fraction: Flo actual fun Modifier.fillMaxHeight(@FloatRange(from = 0.0, to = 1.0) fraction: Float): Modifier = platformModify { fillMaxHeight(fraction) } +@Stable actual fun Modifier.fillMaxSize(@FloatRange(from = 0.0, to = 1.0) fraction: Float): Modifier = platformModify { fillMaxSize(fraction) } + +@Stable +actual fun Modifier.wrapContentWidth(): Modifier = + platformModify { wrapContentWidth() } + +@Stable +actual fun Modifier.wrapContentHeight(): Modifier = + platformModify { wrapContentHeight() } + +@Stable +actual fun Modifier.wrapContentSize(): Modifier = + platformModify { wrapContentSize() } diff --git a/compose-multiplatform-common/src/commonMain/kotlin/com/huanshankeji/compose/layout/Size.kt b/compose-multiplatform-common/src/commonMain/kotlin/com/huanshankeji/compose/layout/Size.kt index 25b28433..adadf23d 100644 --- a/compose-multiplatform-common/src/commonMain/kotlin/com/huanshankeji/compose/layout/Size.kt +++ b/compose-multiplatform-common/src/commonMain/kotlin/com/huanshankeji/compose/layout/Size.kt @@ -42,4 +42,14 @@ expect fun Modifier.fillMaxWidth(@FloatRange(from = 0.0, to = 1.0) fraction: Flo @Stable expect fun Modifier.fillMaxHeight(@FloatRange(from = 0.0, to = 1.0) fraction: Float = 1f): Modifier +@Stable expect fun Modifier.fillMaxSize(@FloatRange(from = 0.0, to = 1.0) fraction: Float = 1f): Modifier + +@Stable +expect fun Modifier.wrapContentWidth() : Modifier + +@Stable +expect fun Modifier.wrapContentHeight() : Modifier + +@Stable +expect fun Modifier.wrapContentSize() : Modifier diff --git a/compose-multiplatform-common/src/jsMain/kotlin/com/huanshankeji/compose/layout/Size.js.kt b/compose-multiplatform-common/src/jsMain/kotlin/com/huanshankeji/compose/layout/Size.js.kt index c3fb36de..124ec2db 100644 --- a/compose-multiplatform-common/src/jsMain/kotlin/com/huanshankeji/compose/layout/Size.js.kt +++ b/compose-multiplatform-common/src/jsMain/kotlin/com/huanshankeji/compose/layout/Size.js.kt @@ -6,6 +6,10 @@ import androidx.compose.ui.unit.Dp import com.huanshankeji.compose.ui.Modifier import com.huanshankeji.compose.ui.unit.toPercent import com.huanshankeji.compose.ui.unit.toPx +import com.huanshankeji.kobweb.compose.ui.modifiers.size +import com.huanshankeji.kobweb.compose.ui.modifiers.sizeFitContent +import com.varabyte.kobweb.compose.css.Height +import com.varabyte.kobweb.compose.css.Width import com.varabyte.kobweb.compose.ui.modifiers.* @Stable @@ -49,5 +53,18 @@ actual fun Modifier.fillMaxWidth(@FloatRange(from = 0.0, to = 1.0) fraction: Flo actual fun Modifier.fillMaxHeight(@FloatRange(from = 0.0, to = 1.0) fraction: Float): Modifier = platformModify { fillMaxHeight(fraction.toPercent()) } +@Stable actual fun Modifier.fillMaxSize(@FloatRange(from = 0.0, to = 1.0) fraction: Float): Modifier = platformModify { fillMaxSize(fraction.toPercent()) } + +@Stable +actual fun Modifier.wrapContentWidth(): Modifier = + platformModify { width(Width.FitContent) } + +@Stable +actual fun Modifier.wrapContentHeight(): Modifier = + platformModify { height(Height.FitContent) } + +@Stable +actual fun Modifier.wrapContentSize(): Modifier = + platformModify { sizeFitContent() } diff --git a/compose-multiplatform-common/src/jsMain/kotlin/com/huanshankeji/kobweb/compose/ui/modifiers/Size.kt b/compose-multiplatform-common/src/jsMain/kotlin/com/huanshankeji/kobweb/compose/ui/modifiers/Size.kt index 3f9eb0b4..7b2b8c02 100644 --- a/compose-multiplatform-common/src/jsMain/kotlin/com/huanshankeji/kobweb/compose/ui/modifiers/Size.kt +++ b/compose-multiplatform-common/src/jsMain/kotlin/com/huanshankeji/kobweb/compose/ui/modifiers/Size.kt @@ -17,5 +17,6 @@ fun Modifier.size(width: Width, height: Height): Modifier = width(width).height(height) +//TODO consider removing and inlining this fun Modifier.sizeFitContent() = size(Width.FitContent, Height.FitContent) From 0a93a92ba2e2f85df2b00f077ed85f715b5dc004 Mon Sep 17 00:00:00 2001 From: Shreck Ye Date: Sun, 21 Apr 2024 18:25:17 +0800 Subject: [PATCH 23/75] Improve `Modifier.size` This was not working probably because the wrong extension functions were imported and invoked. --- .../huanshankeji/kobweb/compose/ui/modifiers/Size.kt | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/compose-multiplatform-common/src/jsMain/kotlin/com/huanshankeji/kobweb/compose/ui/modifiers/Size.kt b/compose-multiplatform-common/src/jsMain/kotlin/com/huanshankeji/kobweb/compose/ui/modifiers/Size.kt index 7b2b8c02..6514c192 100644 --- a/compose-multiplatform-common/src/jsMain/kotlin/com/huanshankeji/kobweb/compose/ui/modifiers/Size.kt +++ b/compose-multiplatform-common/src/jsMain/kotlin/com/huanshankeji/kobweb/compose/ui/modifiers/Size.kt @@ -2,20 +2,16 @@ package com.huanshankeji.kobweb.compose.ui.modifiers import com.varabyte.kobweb.compose.css.Height import com.varabyte.kobweb.compose.css.Width +import com.varabyte.kobweb.compose.css.height +import com.varabyte.kobweb.compose.css.width import com.varabyte.kobweb.compose.ui.Modifier -import com.varabyte.kobweb.compose.ui.modifiers.height -import com.varabyte.kobweb.compose.ui.modifiers.width +import com.varabyte.kobweb.compose.ui.styleModifier fun Modifier.size(width: Width, height: Height): Modifier = - /* - // not working styleModifier { width(width) height(height) } - */ - width(width).height(height) - //TODO consider removing and inlining this fun Modifier.sizeFitContent() = From b559612ebaaa54031d7f92e450ab705dbe47abf3 Mon Sep 17 00:00:00 2001 From: Shreck Ye Date: Mon, 22 Apr 2024 14:59:35 +0800 Subject: [PATCH 24/75] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index da749ebb..eca83660 100644 --- a/README.md +++ b/README.md @@ -103,7 +103,7 @@ repositories { ## About Kobweb Silk -The Kotlin/JS (Compose HTML) portion of this project depends on [Kobweb Compose](https://github.com/varabyte/kobweb/blob/main/frontend/kobweb-compose/README.md) of [Kobweb Silk](https://github.com/varabyte/kobweb?tab=readme-ov-file#silk) which is a UI layer built upon Compose HTML that provides `Modifier` APIs (type-safe CSS API wrappers) and layouts. Here is a list of topics in their README.md that should be helpful when you use this library in Compose HTML: +The Kotlin/JS (Compose HTML) portion of this project depends on [Kobweb Compose](https://github.com/varabyte/kobweb/blob/main/frontend/kobweb-compose/README.md) of [Kobweb Silk](https://github.com/varabyte/kobweb?tab=readme-ov-file#silk) which is a UI layer built upon Compose HTML that provides `Modifier` (type-safe CSS API wrappers) and layout APIs. Here is a list of topics in their README.md that should be helpful when you use this library in Compose HTML, especially if you need to customize the components further on Kotlin/JS (Compose HTML): 1. [Silk](https://github.com/varabyte/kobweb?tab=readme-ov-file#silk) 1. [Modifier](https://github.com/varabyte/kobweb?tab=readme-ov-file#modifier) From 1315e2924672de29b12b64fc3f4f9f7885230f5c Mon Sep 17 00:00:00 2001 From: Shreck Ye Date: Tue, 23 Apr 2024 11:09:54 +0800 Subject: [PATCH 25/75] Add a `Divider` composable that's visually inconsistent now The divider line shows as a small centered dot on JS with its `margin` taking all the space. This has to be investigated further. --- README.md | 1 + .../compose/material/Divider.androidxCommon.kt | 8 ++++++++ .../com/huanshankeji/compose/material/Divider.kt | 12 ++++++++++++ .../com/huanshankeji/compose/material/Divider.js.kt | 13 +++++++++++++ .../com/huanshankeji/compose/material/demo/App.kt | 2 ++ 5 files changed, 36 insertions(+) create mode 100644 compose-multiplatform-material/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material/Divider.androidxCommon.kt create mode 100644 compose-multiplatform-material/src/commonMain/kotlin/com/huanshankeji/compose/material/Divider.kt create mode 100644 compose-multiplatform-material/src/jsMain/kotlin/com/huanshankeji/compose/material/Divider.js.kt diff --git a/README.md b/README.md index eca83660..79952efb 100644 --- a/README.md +++ b/README.md @@ -41,6 +41,7 @@ This project is prototype and there is no documentation yet. Check out [the demo - `Text`/`MaterialText` - `TextField` - `Checkbox` +- `Divider` (visually inconsistent for now) ##### `ext` components diff --git a/compose-multiplatform-material/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material/Divider.androidxCommon.kt b/compose-multiplatform-material/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material/Divider.androidxCommon.kt new file mode 100644 index 00000000..92ac8ecd --- /dev/null +++ b/compose-multiplatform-material/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material/Divider.androidxCommon.kt @@ -0,0 +1,8 @@ +package com.huanshankeji.compose.material + +import androidx.compose.runtime.Composable +import com.huanshankeji.compose.ui.Modifier + +@Composable +actual fun Divider(modifier: Modifier) = + androidx.compose.material.Divider(modifier.platformModifier) diff --git a/compose-multiplatform-material/src/commonMain/kotlin/com/huanshankeji/compose/material/Divider.kt b/compose-multiplatform-material/src/commonMain/kotlin/com/huanshankeji/compose/material/Divider.kt new file mode 100644 index 00000000..6159c27f --- /dev/null +++ b/compose-multiplatform-material/src/commonMain/kotlin/com/huanshankeji/compose/material/Divider.kt @@ -0,0 +1,12 @@ +package com.huanshankeji.compose.material + +import androidx.compose.runtime.Composable +import com.huanshankeji.compose.ui.Modifier + +@Composable +expect fun Divider( + modifier: Modifier = Modifier, + //color: Color, + //thickness: Dp = 1.dp, + //startIndent: Dp = 0.dp +) diff --git a/compose-multiplatform-material/src/jsMain/kotlin/com/huanshankeji/compose/material/Divider.js.kt b/compose-multiplatform-material/src/jsMain/kotlin/com/huanshankeji/compose/material/Divider.js.kt new file mode 100644 index 00000000..e9394053 --- /dev/null +++ b/compose-multiplatform-material/src/jsMain/kotlin/com/huanshankeji/compose/material/Divider.js.kt @@ -0,0 +1,13 @@ +package com.huanshankeji.compose.material + +import androidx.compose.runtime.Composable +import com.huanshankeji.compose.ui.Modifier +import com.varabyte.kobweb.compose.ui.toAttrs +import org.jetbrains.compose.web.dom.Hr + +// https://developer.mozilla.org/en-US/docs/Web/HTML/Element/hr +// see: https://github.com/varabyte/kobweb/blob/main/frontend/silk-widgets/src/jsMain/kotlin/com/varabyte/kobweb/silk/components/layout/Divider.kt +// see: https://github.com/mpetuska/kmdc/blob/master/katalog/katalog-runtime/src/jsMain/kotlin/layout/Divider.kt +@Composable +actual fun Divider(modifier: Modifier) = + Hr(modifier.platformModifier.toAttrs()) diff --git a/demo/src/commonMain/kotlin/com/huanshankeji/compose/material/demo/App.kt b/demo/src/commonMain/kotlin/com/huanshankeji/compose/material/demo/App.kt index 97d4b1e0..36d1fd1f 100644 --- a/demo/src/commonMain/kotlin/com/huanshankeji/compose/material/demo/App.kt +++ b/demo/src/commonMain/kotlin/com/huanshankeji/compose/material/demo/App.kt @@ -96,6 +96,8 @@ fun App() { ColorBox(Color(1f, 0f, 0f, 0.5f)) } + Divider() + Row { @Composable fun NestedColorBox(modifier: Modifier) = From eed69f889b3cc67e1080ec039d05cf07d854f87d Mon Sep 17 00:00:00 2001 From: Shreck Ye Date: Tue, 23 Apr 2024 11:18:36 +0800 Subject: [PATCH 26/75] Add a background color to the demo `Column` to highlight its area --- .../kotlin/com/huanshankeji/compose/material/demo/App.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/demo/src/commonMain/kotlin/com/huanshankeji/compose/material/demo/App.kt b/demo/src/commonMain/kotlin/com/huanshankeji/compose/material/demo/App.kt index 36d1fd1f..3704da02 100644 --- a/demo/src/commonMain/kotlin/com/huanshankeji/compose/material/demo/App.kt +++ b/demo/src/commonMain/kotlin/com/huanshankeji/compose/material/demo/App.kt @@ -41,7 +41,7 @@ fun App() { MaterialIconActionButton({}, Icons.Default.Search, "search") }) { Card(Modifier.padding(16.dp).height(800.dp).width(400.dp)) { - Column(Modifier.padding(16.dp)) { + Column(Modifier.padding(16.dp).background(Color(0xF8, 0xF8, 0xF8, 0xFF))) { BasicText("basic text 1") BasicText("basic text 2") Text("Material text") From 9751ee96b7fec2213d658af23ea765f2ea291d14 Mon Sep 17 00:00:00 2001 From: Shreck Ye Date: Wed, 24 Apr 2024 06:44:05 +0800 Subject: [PATCH 27/75] Add `IntrinsicSize` and related modifiers that are not tested yet --- .../layout/Intrinsic.androidxCommon.kt | 21 +++++++++++++++++++ .../huanshankeji/compose/layout/Intrinsic.kt | 12 +++++++++++ .../com/huanshankeji/compose/layout/Size.kt | 6 +++--- .../compose/layout/Intrinsic.js.kt | 16 ++++++++++++++ 4 files changed, 52 insertions(+), 3 deletions(-) create mode 100644 compose-multiplatform-common/src/androidxCommonMain/kotlin/com/huanshankeji/compose/layout/Intrinsic.androidxCommon.kt create mode 100644 compose-multiplatform-common/src/commonMain/kotlin/com/huanshankeji/compose/layout/Intrinsic.kt create mode 100644 compose-multiplatform-common/src/jsMain/kotlin/com/huanshankeji/compose/layout/Intrinsic.js.kt diff --git a/compose-multiplatform-common/src/androidxCommonMain/kotlin/com/huanshankeji/compose/layout/Intrinsic.androidxCommon.kt b/compose-multiplatform-common/src/androidxCommonMain/kotlin/com/huanshankeji/compose/layout/Intrinsic.androidxCommon.kt new file mode 100644 index 00000000..836383f0 --- /dev/null +++ b/compose-multiplatform-common/src/androidxCommonMain/kotlin/com/huanshankeji/compose/layout/Intrinsic.androidxCommon.kt @@ -0,0 +1,21 @@ +package com.huanshankeji.compose.layout + +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.width +import androidx.compose.runtime.Stable +import com.huanshankeji.compose.ui.Modifier +import androidx.compose.foundation.layout.IntrinsicSize as PlatformIntrinsicSize + +@Stable +actual fun Modifier.width(intrinsicSize: IntrinsicSize): Modifier = + platformModify { width(intrinsicSize.toPlatformValue()) } + +@Stable +actual fun Modifier.height(intrinsicSize: IntrinsicSize): Modifier = + platformModify { height(intrinsicSize.toPlatformValue()) } + +fun IntrinsicSize.toPlatformValue() = + when (this) { + IntrinsicSize.Min -> PlatformIntrinsicSize.Min + IntrinsicSize.Max -> PlatformIntrinsicSize.Max + } diff --git a/compose-multiplatform-common/src/commonMain/kotlin/com/huanshankeji/compose/layout/Intrinsic.kt b/compose-multiplatform-common/src/commonMain/kotlin/com/huanshankeji/compose/layout/Intrinsic.kt new file mode 100644 index 00000000..52ce3016 --- /dev/null +++ b/compose-multiplatform-common/src/commonMain/kotlin/com/huanshankeji/compose/layout/Intrinsic.kt @@ -0,0 +1,12 @@ +package com.huanshankeji.compose.layout + +import androidx.compose.runtime.Stable +import com.huanshankeji.compose.ui.Modifier + +@Stable +expect fun Modifier.width(intrinsicSize: IntrinsicSize): Modifier + +@Stable +expect fun Modifier.height(intrinsicSize: IntrinsicSize): Modifier + +enum class IntrinsicSize { Min, Max } diff --git a/compose-multiplatform-common/src/commonMain/kotlin/com/huanshankeji/compose/layout/Size.kt b/compose-multiplatform-common/src/commonMain/kotlin/com/huanshankeji/compose/layout/Size.kt index adadf23d..d6c73270 100644 --- a/compose-multiplatform-common/src/commonMain/kotlin/com/huanshankeji/compose/layout/Size.kt +++ b/compose-multiplatform-common/src/commonMain/kotlin/com/huanshankeji/compose/layout/Size.kt @@ -46,10 +46,10 @@ expect fun Modifier.fillMaxHeight(@FloatRange(from = 0.0, to = 1.0) fraction: Fl expect fun Modifier.fillMaxSize(@FloatRange(from = 0.0, to = 1.0) fraction: Float = 1f): Modifier @Stable -expect fun Modifier.wrapContentWidth() : Modifier +expect fun Modifier.wrapContentWidth(): Modifier @Stable -expect fun Modifier.wrapContentHeight() : Modifier +expect fun Modifier.wrapContentHeight(): Modifier @Stable -expect fun Modifier.wrapContentSize() : Modifier +expect fun Modifier.wrapContentSize(): Modifier diff --git a/compose-multiplatform-common/src/jsMain/kotlin/com/huanshankeji/compose/layout/Intrinsic.js.kt b/compose-multiplatform-common/src/jsMain/kotlin/com/huanshankeji/compose/layout/Intrinsic.js.kt new file mode 100644 index 00000000..533ab4ad --- /dev/null +++ b/compose-multiplatform-common/src/jsMain/kotlin/com/huanshankeji/compose/layout/Intrinsic.js.kt @@ -0,0 +1,16 @@ +package com.huanshankeji.compose.layout + +import androidx.compose.runtime.Stable +import com.huanshankeji.compose.ui.Modifier +import com.varabyte.kobweb.compose.ui.modifiers.width +import org.jetbrains.compose.web.css.percent + +// TODO are there better values than `100.percent`? + +@Stable +actual fun Modifier.width(intrinsicSize: IntrinsicSize): Modifier = + platformModify { width(100.percent) } + +@Stable +actual fun Modifier.height(intrinsicSize: IntrinsicSize): Modifier = + platformModify { width(100.percent) } From 545180238991177783537d5213248269011709a6 Mon Sep 17 00:00:00 2001 From: Shreck Ye Date: Wed, 24 Apr 2024 07:52:04 +0800 Subject: [PATCH 28/75] Temporarily deprecate the code added in commit 9751ee96b7fec2213d658af23ea765f2ea291d14 --- .../kotlin/com/huanshankeji/compose/layout/Intrinsic.kt | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/compose-multiplatform-common/src/commonMain/kotlin/com/huanshankeji/compose/layout/Intrinsic.kt b/compose-multiplatform-common/src/commonMain/kotlin/com/huanshankeji/compose/layout/Intrinsic.kt index 52ce3016..0f371ee2 100644 --- a/compose-multiplatform-common/src/commonMain/kotlin/com/huanshankeji/compose/layout/Intrinsic.kt +++ b/compose-multiplatform-common/src/commonMain/kotlin/com/huanshankeji/compose/layout/Intrinsic.kt @@ -3,10 +3,16 @@ package com.huanshankeji.compose.layout import androidx.compose.runtime.Stable import com.huanshankeji.compose.ui.Modifier +private const val DEPRECATION_MESSAGE = + "This API doesn't work as expected, is not consistent on both platforms, and is temporarily deprecated." + +@Deprecated(DEPRECATION_MESSAGE) @Stable expect fun Modifier.width(intrinsicSize: IntrinsicSize): Modifier +@Deprecated(DEPRECATION_MESSAGE) @Stable expect fun Modifier.height(intrinsicSize: IntrinsicSize): Modifier +@Deprecated(DEPRECATION_MESSAGE) enum class IntrinsicSize { Min, Max } From 687ada926ca63ac95dfeb8536a36405d23d2c44e Mon Sep 17 00:00:00 2001 From: Shreck Ye Date: Wed, 24 Apr 2024 08:11:37 +0800 Subject: [PATCH 29/75] Fix the `IntrinsicSize` modifiers to delegate to `min-content` and `max-content` on JS Also fix a bug caused by `height` delegating to `width`. --- .../compose/layout/Intrinsic.js.kt | 24 +++++++++++++++---- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/compose-multiplatform-common/src/jsMain/kotlin/com/huanshankeji/compose/layout/Intrinsic.js.kt b/compose-multiplatform-common/src/jsMain/kotlin/com/huanshankeji/compose/layout/Intrinsic.js.kt index 533ab4ad..573b73c3 100644 --- a/compose-multiplatform-common/src/jsMain/kotlin/com/huanshankeji/compose/layout/Intrinsic.js.kt +++ b/compose-multiplatform-common/src/jsMain/kotlin/com/huanshankeji/compose/layout/Intrinsic.js.kt @@ -2,15 +2,29 @@ package com.huanshankeji.compose.layout import androidx.compose.runtime.Stable import com.huanshankeji.compose.ui.Modifier +import com.varabyte.kobweb.compose.css.Height +import com.varabyte.kobweb.compose.css.Width +import com.varabyte.kobweb.compose.ui.modifiers.height import com.varabyte.kobweb.compose.ui.modifiers.width -import org.jetbrains.compose.web.css.percent - -// TODO are there better values than `100.percent`? @Stable actual fun Modifier.width(intrinsicSize: IntrinsicSize): Modifier = - platformModify { width(100.percent) } + platformModify { + width( + when (intrinsicSize) { + IntrinsicSize.Min -> Width.MinContent + IntrinsicSize.Max -> Width.MaxContent + } + ) + } @Stable actual fun Modifier.height(intrinsicSize: IntrinsicSize): Modifier = - platformModify { width(100.percent) } + platformModify { + height( + when (intrinsicSize) { + IntrinsicSize.Min -> Height.MinContent + IntrinsicSize.Max -> Height.MaxContent + } + ) + } From ec4706270e414d118dc96048d6f4b0c6aa70ecff Mon Sep 17 00:00:00 2001 From: Shreck Ye Date: Wed, 24 Apr 2024 08:59:05 +0800 Subject: [PATCH 30/75] Apply `KobwebComposeStyleSheet` and fix the bug that `Arrangement` and `Alignment` didn't work in `Row` and `Column` --- .../huanshankeji/compose/foundation/layout/Box.js.kt | 4 +++- .../compose/foundation/layout/Column.js.kt | 10 ++++------ .../compose/foundation/layout/KobwebCompose.kt | 9 +++++++++ .../huanshankeji/compose/foundation/layout/Row.js.kt | 11 ++++------- 4 files changed, 20 insertions(+), 14 deletions(-) create mode 100644 compose-multiplatform-common/src/jsMain/kotlin/com/huanshankeji/compose/foundation/layout/KobwebCompose.kt diff --git a/compose-multiplatform-common/src/jsMain/kotlin/com/huanshankeji/compose/foundation/layout/Box.js.kt b/compose-multiplatform-common/src/jsMain/kotlin/com/huanshankeji/compose/foundation/layout/Box.js.kt index 8d23c415..8035d663 100644 --- a/compose-multiplatform-common/src/jsMain/kotlin/com/huanshankeji/compose/foundation/layout/Box.js.kt +++ b/compose-multiplatform-common/src/jsMain/kotlin/com/huanshankeji/compose/foundation/layout/Box.js.kt @@ -16,11 +16,13 @@ actual fun Box( modifier: Modifier, contentAlignment: Alignment, content: @Composable BoxScope.() -> Unit -) = +) { + AddKobwebComposeStyleSheet() PlatformBox( PlatformModifier.sizeFitContent().then(modifier.platformModifier), contentAlignment.platformValue, ) { BoxScope.Impl(this).content() } +} @Composable actual fun Box(modifier: Modifier) = diff --git a/compose-multiplatform-common/src/jsMain/kotlin/com/huanshankeji/compose/foundation/layout/Column.js.kt b/compose-multiplatform-common/src/jsMain/kotlin/com/huanshankeji/compose/foundation/layout/Column.js.kt index 4a0d132f..8f656169 100644 --- a/compose-multiplatform-common/src/jsMain/kotlin/com/huanshankeji/compose/foundation/layout/Column.js.kt +++ b/compose-multiplatform-common/src/jsMain/kotlin/com/huanshankeji/compose/foundation/layout/Column.js.kt @@ -6,10 +6,6 @@ import com.huanshankeji.compose.ui.Alignment import com.huanshankeji.compose.ui.Modifier import com.huanshankeji.kobweb.compose.ui.modifiers.sizeFitContent import com.varabyte.kobweb.compose.foundation.layout.LayoutScopeMarker -import com.varabyte.kobweb.compose.ui.modifiers.display -import com.varabyte.kobweb.compose.ui.modifiers.flexDirection -import org.jetbrains.compose.web.css.DisplayStyle -import org.jetbrains.compose.web.css.FlexDirection import com.varabyte.kobweb.compose.foundation.layout.ColumnScope as PlatformColumnScope import com.varabyte.kobweb.compose.ui.Modifier as PlatformModifier @@ -19,14 +15,16 @@ actual fun Column( verticalArrangement: Arrangement.Vertical, horizontalAlignment: Alignment.Horizontal, content: @Composable ColumnScope.() -> Unit -) = +) { + AddKobwebComposeStyleSheet() com.varabyte.kobweb.compose.foundation.layout.Column( - PlatformModifier.display(DisplayStyle.Flex).flexDirection(FlexDirection.Column) + PlatformModifier .sizeFitContent() // "fit-content" is added to make it consistent with the `androidx` one .then(modifier.platformModifier), verticalArrangement.platformValue, horizontalAlignment.platformValue ) { ColumnScope.Impl(this).content() } +} @LayoutScopeMarker actual interface ColumnScope { diff --git a/compose-multiplatform-common/src/jsMain/kotlin/com/huanshankeji/compose/foundation/layout/KobwebCompose.kt b/compose-multiplatform-common/src/jsMain/kotlin/com/huanshankeji/compose/foundation/layout/KobwebCompose.kt new file mode 100644 index 00000000..f51ea21e --- /dev/null +++ b/compose-multiplatform-common/src/jsMain/kotlin/com/huanshankeji/compose/foundation/layout/KobwebCompose.kt @@ -0,0 +1,9 @@ +package com.huanshankeji.compose.foundation.layout + +import androidx.compose.runtime.Composable +import com.varabyte.kobweb.compose.style.KobwebComposeStyleSheet +import org.jetbrains.compose.web.css.Style + +@Composable +fun AddKobwebComposeStyleSheet() = + Style(KobwebComposeStyleSheet) diff --git a/compose-multiplatform-common/src/jsMain/kotlin/com/huanshankeji/compose/foundation/layout/Row.js.kt b/compose-multiplatform-common/src/jsMain/kotlin/com/huanshankeji/compose/foundation/layout/Row.js.kt index e628cfa7..0339efe1 100644 --- a/compose-multiplatform-common/src/jsMain/kotlin/com/huanshankeji/compose/foundation/layout/Row.js.kt +++ b/compose-multiplatform-common/src/jsMain/kotlin/com/huanshankeji/compose/foundation/layout/Row.js.kt @@ -6,12 +6,7 @@ import com.huanshankeji.compose.ui.Alignment import com.huanshankeji.compose.ui.Modifier import com.huanshankeji.kobweb.compose.ui.modifiers.sizeFitContent import com.varabyte.kobweb.compose.foundation.layout.LayoutScopeMarker -import com.varabyte.kobweb.compose.ui.modifiers.display -import com.varabyte.kobweb.compose.ui.modifiers.flexDirection -import org.jetbrains.compose.web.css.DisplayStyle -import org.jetbrains.compose.web.css.FlexDirection import com.varabyte.kobweb.compose.foundation.layout.RowScope as PlatformRowScope - import com.varabyte.kobweb.compose.ui.Modifier as PlatformModifier @Composable @@ -20,14 +15,16 @@ actual fun Row( horizontalArrangement: Arrangement.Horizontal, verticalAlignment: Alignment.Vertical, content: @Composable RowScope.() -> Unit -) = +) { + AddKobwebComposeStyleSheet() com.varabyte.kobweb.compose.foundation.layout.Row( - PlatformModifier.display(DisplayStyle.Flex).flexDirection(FlexDirection.Row) + PlatformModifier .sizeFitContent() .then(modifier.platformModifier), horizontalArrangement.platformValue, verticalAlignment.platformValue ) { RowScope.Impl(this).content() } +} @LayoutScopeMarker actual interface RowScope { From 85eda57a0a4e4d15aa75564f61a863e1bd0b1f0e Mon Sep 17 00:00:00 2001 From: Shreck Ye Date: Wed, 24 Apr 2024 09:33:51 +0800 Subject: [PATCH 31/75] Add the `Spacer` composable --- .../foundation/layout/Spacer.androidxCommon.kt | 8 ++++++++ .../compose/foundation/layout/Spacer.kt | 7 +++++++ .../compose/foundation/layout/KobwebCompose.kt | 2 +- .../compose/foundation/layout/Spacer.js.kt | 13 +++++++++++++ 4 files changed, 29 insertions(+), 1 deletion(-) create mode 100644 compose-multiplatform-common/src/androidxCommonMain/kotlin/com/huanshankeji/compose/foundation/layout/Spacer.androidxCommon.kt create mode 100644 compose-multiplatform-common/src/commonMain/kotlin/com/huanshankeji/compose/foundation/layout/Spacer.kt create mode 100644 compose-multiplatform-common/src/jsMain/kotlin/com/huanshankeji/compose/foundation/layout/Spacer.js.kt diff --git a/compose-multiplatform-common/src/androidxCommonMain/kotlin/com/huanshankeji/compose/foundation/layout/Spacer.androidxCommon.kt b/compose-multiplatform-common/src/androidxCommonMain/kotlin/com/huanshankeji/compose/foundation/layout/Spacer.androidxCommon.kt new file mode 100644 index 00000000..f762f66c --- /dev/null +++ b/compose-multiplatform-common/src/androidxCommonMain/kotlin/com/huanshankeji/compose/foundation/layout/Spacer.androidxCommon.kt @@ -0,0 +1,8 @@ +package com.huanshankeji.compose.foundation.layout + +import androidx.compose.runtime.Composable +import com.huanshankeji.compose.ui.Modifier + +@Composable +actual fun Spacer(modifier: Modifier) = + androidx.compose.foundation.layout.Spacer(modifier.platformModifier) diff --git a/compose-multiplatform-common/src/commonMain/kotlin/com/huanshankeji/compose/foundation/layout/Spacer.kt b/compose-multiplatform-common/src/commonMain/kotlin/com/huanshankeji/compose/foundation/layout/Spacer.kt new file mode 100644 index 00000000..3e010922 --- /dev/null +++ b/compose-multiplatform-common/src/commonMain/kotlin/com/huanshankeji/compose/foundation/layout/Spacer.kt @@ -0,0 +1,7 @@ +package com.huanshankeji.compose.foundation.layout + +import androidx.compose.runtime.Composable +import com.huanshankeji.compose.ui.Modifier + +@Composable +expect fun Spacer(modifier: Modifier) diff --git a/compose-multiplatform-common/src/jsMain/kotlin/com/huanshankeji/compose/foundation/layout/KobwebCompose.kt b/compose-multiplatform-common/src/jsMain/kotlin/com/huanshankeji/compose/foundation/layout/KobwebCompose.kt index f51ea21e..d0796c6d 100644 --- a/compose-multiplatform-common/src/jsMain/kotlin/com/huanshankeji/compose/foundation/layout/KobwebCompose.kt +++ b/compose-multiplatform-common/src/jsMain/kotlin/com/huanshankeji/compose/foundation/layout/KobwebCompose.kt @@ -5,5 +5,5 @@ import com.varabyte.kobweb.compose.style.KobwebComposeStyleSheet import org.jetbrains.compose.web.css.Style @Composable -fun AddKobwebComposeStyleSheet() = +internal fun AddKobwebComposeStyleSheet() = Style(KobwebComposeStyleSheet) diff --git a/compose-multiplatform-common/src/jsMain/kotlin/com/huanshankeji/compose/foundation/layout/Spacer.js.kt b/compose-multiplatform-common/src/jsMain/kotlin/com/huanshankeji/compose/foundation/layout/Spacer.js.kt new file mode 100644 index 00000000..49b00149 --- /dev/null +++ b/compose-multiplatform-common/src/jsMain/kotlin/com/huanshankeji/compose/foundation/layout/Spacer.js.kt @@ -0,0 +1,13 @@ +package com.huanshankeji.compose.foundation.layout + +import androidx.compose.runtime.Composable +import com.huanshankeji.compose.ui.Modifier +import com.varabyte.kobweb.compose.ui.toAttrs +import org.jetbrains.compose.web.dom.Div + +@Composable +actual fun Spacer(modifier: Modifier) { + AddKobwebComposeStyleSheet() + Div(attrs = modifier.platformModifier.toAttrs { classes("kobweb-spacer") }) + //com.varabyte.kobweb.compose.foundation.layout.Spacer() // use this when `Modifier` is supported +} From 2daac25c712e49a565094e6d4bb4bf56822cc468 Mon Sep 17 00:00:00 2001 From: Shreck Ye Date: Wed, 24 Apr 2024 09:35:05 +0800 Subject: [PATCH 32/75] Revert "Temporarily deprecate the code added in commit 9751ee96b7fec2213d658af23ea765f2ea291d14" This reverts commit 545180238991177783537d5213248269011709a6. --- .../kotlin/com/huanshankeji/compose/layout/Intrinsic.kt | 6 ------ 1 file changed, 6 deletions(-) diff --git a/compose-multiplatform-common/src/commonMain/kotlin/com/huanshankeji/compose/layout/Intrinsic.kt b/compose-multiplatform-common/src/commonMain/kotlin/com/huanshankeji/compose/layout/Intrinsic.kt index 0f371ee2..52ce3016 100644 --- a/compose-multiplatform-common/src/commonMain/kotlin/com/huanshankeji/compose/layout/Intrinsic.kt +++ b/compose-multiplatform-common/src/commonMain/kotlin/com/huanshankeji/compose/layout/Intrinsic.kt @@ -3,16 +3,10 @@ package com.huanshankeji.compose.layout import androidx.compose.runtime.Stable import com.huanshankeji.compose.ui.Modifier -private const val DEPRECATION_MESSAGE = - "This API doesn't work as expected, is not consistent on both platforms, and is temporarily deprecated." - -@Deprecated(DEPRECATION_MESSAGE) @Stable expect fun Modifier.width(intrinsicSize: IntrinsicSize): Modifier -@Deprecated(DEPRECATION_MESSAGE) @Stable expect fun Modifier.height(intrinsicSize: IntrinsicSize): Modifier -@Deprecated(DEPRECATION_MESSAGE) enum class IntrinsicSize { Min, Max } From c3c6828c1458b575c38c19f64d47f73d871d4318 Mon Sep 17 00:00:00 2001 From: Shreck Ye Date: Wed, 24 Apr 2024 09:48:17 +0800 Subject: [PATCH 33/75] Update `Color.Green` on JS to match the Compose one --- .../kotlin/com/huanshankeji/compose/ui/graphics/Color.js.kt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/compose-multiplatform-common/src/jsMain/kotlin/com/huanshankeji/compose/ui/graphics/Color.js.kt b/compose-multiplatform-common/src/jsMain/kotlin/com/huanshankeji/compose/ui/graphics/Color.js.kt index fb3a3a13..8a68a73e 100644 --- a/compose-multiplatform-common/src/jsMain/kotlin/com/huanshankeji/compose/ui/graphics/Color.js.kt +++ b/compose-multiplatform-common/src/jsMain/kotlin/com/huanshankeji/compose/ui/graphics/Color.js.kt @@ -32,8 +32,9 @@ actual /*value*/ class Color(val platformValue: PlatformColor) { @Stable actual val Red: Color = Color(PlatformColors.Red) + // The CSS green is #008000 which differs from the Compose one. @Stable - actual val Green: Color = Color(PlatformColors.Green) + actual val Green: Color = Color(PlatformColor.rgb(0x00, 0xFF, 0x00)) @Stable actual val Blue: Color = Color(PlatformColors.Blue) From eb1ada7d629f3aa8831df4588653d87530e2635b Mon Sep 17 00:00:00 2001 From: Shreck Ye Date: Wed, 24 Apr 2024 16:03:18 +0800 Subject: [PATCH 34/75] Bump dependency versions --- buildSrc/build.gradle.kts | 2 +- buildSrc/src/main/kotlin/VersionsAndDependencies.kt | 9 ++++----- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts index ef8ab1ac..4536c58c 100644 --- a/buildSrc/build.gradle.kts +++ b/buildSrc/build.gradle.kts @@ -12,7 +12,7 @@ repositories { dependencies { implementation(kotlin("gradle-plugin", "1.9.23")) - implementation("org.jetbrains.compose:compose-gradle-plugin:1.6.1") + implementation("org.jetbrains.compose:compose-gradle-plugin:1.6.2") implementation("com.huanshankeji.team:gradle-plugins:0.5.1") implementation("com.android.tools.build:gradle:8.2.2") } diff --git a/buildSrc/src/main/kotlin/VersionsAndDependencies.kt b/buildSrc/src/main/kotlin/VersionsAndDependencies.kt index 7aa349de..e250ab6d 100644 --- a/buildSrc/src/main/kotlin/VersionsAndDependencies.kt +++ b/buildSrc/src/main/kotlin/VersionsAndDependencies.kt @@ -1,14 +1,13 @@ val projectVersion = "0.2.0-SNAPSHOT" object DependencyVersions { - val composeMultiplatform = "1.6.1" // manually specified for "ui-unit" - val kobweb = "0.17.1" + val composeMultiplatform = "1.6.2" // manually specified for "ui-unit" + val kobweb = "0.17.3" val huanshankejiComposeWeb = "0.2.2" val kmdc = "0.1.2" - val materialIcons = "1.13.12" object Androidx { - val activityCompose = "1.8.2" - val compose = "1.6.4" + val activityCompose = "1.9.0" + val compose = "1.6.6" } } From a536d1f9ca991d987c7ec3fdf6b1375aeefc264a Mon Sep 17 00:00:00 2001 From: Shreck Ye Date: Wed, 24 Apr 2024 16:13:10 +0800 Subject: [PATCH 35/75] Use the latest snapshot of "compose-html-material" and run `kotlinUpgradeYarnLock` --- kotlin-js-store/yarn.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/kotlin-js-store/yarn.lock b/kotlin-js-store/yarn.lock index 50f1b578..c81a6b19 100644 --- a/kotlin-js-store/yarn.lock +++ b/kotlin-js-store/yarn.lock @@ -755,10 +755,10 @@ "@material/theme" "^14.0.0" tslib "^2.1.0" -"@material/web@1.4.0": - version "1.4.0" - resolved "https://registry.yarnpkg.com/@material/web/-/web-1.4.0.tgz#2354ae1bcbfd1a81bececfdc35f5bfe8cbce0777" - integrity sha512-+rnQLUc/vsu7vnkr8XxbEhNVEcdkaYxNjykZ18w/nUMrYTEvAi4TRQJAYeEUXMwRcO3mEXBsCKOtHZ+cbmxTLw== +"@material/web@1.4.1": + version "1.4.1" + resolved "https://registry.yarnpkg.com/@material/web/-/web-1.4.1.tgz#116480759d0b5815ea181086d32cc3ccb54a30f6" + integrity sha512-17MZA6Bt7ie6uDc5cVEGtm6frQfm7ASLGVJhJuYJ0W2Fs7Zogd8wJ3ExoYU8jyzv8LEXcfvnZKcvr8dlquGsig== dependencies: lit "^2.7.4 || ^3.0.0" tslib "^2.4.0" From abf90b6660e09046f07422d6a6c9af5df3d4b247 Mon Sep 17 00:00:00 2001 From: Shreck Ye Date: Thu, 25 Apr 2024 14:51:40 +0800 Subject: [PATCH 36/75] Add all the Material 3 buttons and make `FilledButton` the shortcut for button instead of `ElevatedButton` The Compose `Button` is actually by default a filled button instead of an elevated button. The Compose `ElevatedButton` calls `Button` with different default arguments. --- .../material3/Button.androidxCommon.kt | 46 +++++++- .../material3/ext/Button.androidxCommon.kt | 43 +++++++ .../huanshankeji/compose/material3/Button.kt | 41 ++++++- .../compose/material3/ext/Button.kt | 49 +++++++- .../compose/material3/Button.js.kt | 105 +++++++++++++++++- .../compose/material3/ext/Button.js.kt | 46 +++++++- 6 files changed, 323 insertions(+), 7 deletions(-) diff --git a/compose-multiplatform-material3/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material3/Button.androidxCommon.kt b/compose-multiplatform-material3/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material3/Button.androidxCommon.kt index e02c30eb..af67beca 100644 --- a/compose-multiplatform-material3/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material3/Button.androidxCommon.kt +++ b/compose-multiplatform-material3/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material3/Button.androidxCommon.kt @@ -13,4 +13,48 @@ actual fun Button( ) = androidx.compose.material3.Button(onClick, modifier.platformModifier, enabled) { RowScope.Impl(this).content() - } \ No newline at end of file + } + +@Composable +actual fun ElevatedButton( + onClick: () -> Unit, + modifier: Modifier, + enabled: Boolean, + content: @Composable RowScope.() -> Unit +) = + androidx.compose.material3.ElevatedButton(onClick, modifier.platformModifier, enabled) { + RowScope.Impl(this).content() + } + +@Composable +actual fun FilledTonalButton( + onClick: () -> Unit, + modifier: Modifier, + enabled: Boolean, + content: @Composable RowScope.() -> Unit +) = + androidx.compose.material3.FilledTonalButton(onClick, modifier.platformModifier, enabled) { + RowScope.Impl(this).content() + } + +@Composable +actual fun OutlinedButton( + onClick: () -> Unit, + modifier: Modifier, + enabled: Boolean, + content: @Composable RowScope.() -> Unit +) = + androidx.compose.material3.OutlinedButton(onClick, modifier.platformModifier, enabled) { + RowScope.Impl(this).content() + } + +@Composable +actual fun TextButton( + onClick: () -> Unit, + modifier: Modifier, + enabled: Boolean, + content: @Composable RowScope.() -> Unit +) = + androidx.compose.material3.TextButton(onClick, modifier.platformModifier, enabled) { + RowScope.Impl(this).content() + } diff --git a/compose-multiplatform-material3/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material3/ext/Button.androidxCommon.kt b/compose-multiplatform-material3/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material3/ext/Button.androidxCommon.kt index f92617c9..49f37fd9 100644 --- a/compose-multiplatform-material3/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material3/ext/Button.androidxCommon.kt +++ b/compose-multiplatform-material3/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material3/ext/Button.androidxCommon.kt @@ -14,6 +14,49 @@ actual fun Button( ButtonScope.content() } +@Composable +actual fun ElevatedButton( + onClick: () -> Unit, + modifier: Modifier, + enabled: Boolean, + content: @Composable ButtonScope.() -> Unit +) = androidx.compose.material3.ElevatedButton(onClick, modifier.platformModifier, enabled) { + ButtonScope.content() +} + +@Composable +actual fun FilledTonalButton( + onClick: () -> Unit, + modifier: Modifier, + enabled: Boolean, + content: @Composable ButtonScope.() -> Unit +) = + androidx.compose.material3.FilledTonalButton(onClick, modifier.platformModifier, enabled) { + ButtonScope.content() + } + +@Composable +actual fun OutlinedButton( + onClick: () -> Unit, + modifier: Modifier, + enabled: Boolean, + content: @Composable ButtonScope.() -> Unit +) = + androidx.compose.material3.OutlinedButton(onClick, modifier.platformModifier, enabled) { + ButtonScope.content() + } + +@Composable +actual fun TextButton( + onClick: () -> Unit, + modifier: Modifier, + enabled: Boolean, + content: @Composable ButtonScope.() -> Unit +) = + androidx.compose.material3.TextButton(onClick, modifier.platformModifier, enabled) { + ButtonScope.content() + } + actual object ButtonScope { @Composable actual fun Icon() { diff --git a/compose-multiplatform-material3/src/commonMain/kotlin/com/huanshankeji/compose/material3/Button.kt b/compose-multiplatform-material3/src/commonMain/kotlin/com/huanshankeji/compose/material3/Button.kt index f53b40b6..70c4830b 100644 --- a/compose-multiplatform-material3/src/commonMain/kotlin/com/huanshankeji/compose/material3/Button.kt +++ b/compose-multiplatform-material3/src/commonMain/kotlin/com/huanshankeji/compose/material3/Button.kt @@ -4,6 +4,9 @@ import androidx.compose.runtime.Composable import com.huanshankeji.compose.foundation.layout.RowScope import com.huanshankeji.compose.ui.Modifier +/** + * Filled button + */ @Composable expect fun Button( onClick: () -> Unit, @@ -16,11 +19,47 @@ expect fun Button( content: @Composable RowScope.() -> Unit ) +@Deprecated( + "This is a shortcut to `Button`. Use `Button` instead.", + ReplaceWith("Button(onClick, modifier, enabled, content)", "com.huanshankeji.compose.material3.Button") +) @Composable -fun ElevatedButton( +fun FilledButton( onClick: () -> Unit, modifier: Modifier = Modifier, enabled: Boolean = true, content: @Composable RowScope.() -> Unit ) = Button(onClick, modifier, enabled, content) + +@Composable +expect fun ElevatedButton( + onClick: () -> Unit, + modifier: Modifier = Modifier, + enabled: Boolean = true, + content: @Composable RowScope.() -> Unit +) + +@Composable +expect fun FilledTonalButton( + onClick: () -> Unit, + modifier: Modifier = Modifier, + enabled: Boolean = true, + content: @Composable RowScope.() -> Unit +) + +@Composable +expect fun OutlinedButton( + onClick: () -> Unit, + modifier: Modifier = Modifier, + enabled: Boolean = true, + content: @Composable RowScope.() -> Unit +) + +@Composable +expect fun TextButton( + onClick: () -> Unit, + modifier: Modifier = Modifier, + enabled: Boolean = true, + content: @Composable RowScope.() -> Unit +) diff --git a/compose-multiplatform-material3/src/commonMain/kotlin/com/huanshankeji/compose/material3/ext/Button.kt b/compose-multiplatform-material3/src/commonMain/kotlin/com/huanshankeji/compose/material3/ext/Button.kt index ea6fed53..c7c85fdc 100644 --- a/compose-multiplatform-material3/src/commonMain/kotlin/com/huanshankeji/compose/material3/ext/Button.kt +++ b/compose-multiplatform-material3/src/commonMain/kotlin/com/huanshankeji/compose/material3/ext/Button.kt @@ -3,6 +3,9 @@ package com.huanshankeji.compose.material3.ext import androidx.compose.runtime.Composable import com.huanshankeji.compose.ui.Modifier +/** + * filled button + */ @Composable expect fun Button( onClick: () -> Unit, @@ -11,7 +14,51 @@ expect fun Button( content: @Composable ButtonScope.() -> Unit ) +/** + * a shortcut to `Button` + */ +@Composable +fun FilledButton( + onClick: () -> Unit, + modifier: Modifier = Modifier, + enabled: Boolean = true, + content: @Composable ButtonScope.() -> Unit +) = + Button(onClick, modifier, enabled, content) + +@Composable +expect fun ElevatedButton( + onClick: () -> Unit, + modifier: Modifier = Modifier, + enabled: Boolean = true, + content: @Composable ButtonScope.() -> Unit +) + +@Composable +expect fun FilledTonalButton( + onClick: () -> Unit, + modifier: Modifier = Modifier, + enabled: Boolean = true, + content: @Composable ButtonScope.() -> Unit +) + +@Composable +expect fun OutlinedButton( + onClick: () -> Unit, + modifier: Modifier = Modifier, + enabled: Boolean = true, + content: @Composable ButtonScope.() -> Unit +) + +@Composable +expect fun TextButton( + onClick: () -> Unit, + modifier: Modifier = Modifier, + enabled: Boolean = true, + content: @Composable ButtonScope.() -> Unit +) + expect class ButtonScope { @Composable - fun Icon() + fun Icon(/* TODO */) } diff --git a/compose-multiplatform-material3/src/jsMain/kotlin/com/huanshankeji/compose/material3/Button.js.kt b/compose-multiplatform-material3/src/jsMain/kotlin/com/huanshankeji/compose/material3/Button.js.kt index 8e2bcf82..46d18791 100644 --- a/compose-multiplatform-material3/src/jsMain/kotlin/com/huanshankeji/compose/material3/Button.js.kt +++ b/compose-multiplatform-material3/src/jsMain/kotlin/com/huanshankeji/compose/material3/Button.js.kt @@ -3,8 +3,7 @@ package com.huanshankeji.compose.material3 import androidx.compose.runtime.Composable import com.huanshankeji.compose.foundation.layout.Row import com.huanshankeji.compose.foundation.layout.RowScope -import com.huanshankeji.compose.html.material3.MdButtonScope -import com.huanshankeji.compose.html.material3.MdElevatedButton +import com.huanshankeji.compose.html.material3.* import com.huanshankeji.compose.ui.Modifier import com.varabyte.kobweb.compose.ui.toAttrs @@ -15,7 +14,7 @@ internal fun CommonButton( enabled: Boolean, content: @Composable MdButtonScope.() -> Unit ) = - MdElevatedButton(disabled = if (enabled) null else true, + MdFilledButton(disabled = if (enabled) null else true, attrs = modifier.platformModifier.toAttrs { onClick { onClick() } }) { @@ -32,3 +31,103 @@ actual fun Button( CommonButton(onClick, modifier, enabled) { Row(content = content) } + +@Composable +internal fun CommonElevatedButton( + onClick: () -> Unit, + modifier: Modifier, + enabled: Boolean, + content: @Composable MdButtonScope.() -> Unit +) = + MdElevatedButton(disabled = if (enabled) null else true, + attrs = modifier.platformModifier.toAttrs { + onClick { onClick() } + }) { + content() + } + +@Composable +actual fun ElevatedButton( + onClick: () -> Unit, + modifier: Modifier, + enabled: Boolean, + content: @Composable RowScope.() -> Unit +) = + CommonElevatedButton(onClick, modifier, enabled) { + Row(content = content) + } + +@Composable +internal fun CommonFilledTonalButton( + onClick: () -> Unit, + modifier: Modifier, + enabled: Boolean, + content: @Composable MdButtonScope.() -> Unit +) = + MdFilledTonalButton(disabled = if (enabled) null else true, + attrs = modifier.platformModifier.toAttrs { + onClick { onClick() } + }) { + content() + } + +@Composable +actual fun FilledTonalButton( + onClick: () -> Unit, + modifier: Modifier, + enabled: Boolean, + content: @Composable RowScope.() -> Unit +) = + CommonFilledTonalButton(onClick, modifier, enabled) { + Row(content = content) + } + +@Composable +internal fun CommonOutlinedButton( + onClick: () -> Unit, + modifier: Modifier, + enabled: Boolean, + content: @Composable MdButtonScope.() -> Unit +) = + MdOutlinedButton(disabled = if (enabled) null else true, + attrs = modifier.platformModifier.toAttrs { + onClick { onClick() } + }) { + content() + } + +@Composable +actual fun OutlinedButton( + onClick: () -> Unit, + modifier: Modifier, + enabled: Boolean, + content: @Composable RowScope.() -> Unit +) = + CommonOutlinedButton(onClick, modifier, enabled) { + Row(content = content) + } + +@Composable +internal fun CommonTextButton( + onClick: () -> Unit, + modifier: Modifier, + enabled: Boolean, + content: @Composable MdButtonScope.() -> Unit +) = + MdTextButton(disabled = if (enabled) null else true, + attrs = modifier.platformModifier.toAttrs { + onClick { onClick() } + }) { + content() + } + +@Composable +actual fun TextButton( + onClick: () -> Unit, + modifier: Modifier, + enabled: Boolean, + content: @Composable RowScope.() -> Unit +) = + CommonTextButton(onClick, modifier, enabled) { + Row(content = content) + } diff --git a/compose-multiplatform-material3/src/jsMain/kotlin/com/huanshankeji/compose/material3/ext/Button.js.kt b/compose-multiplatform-material3/src/jsMain/kotlin/com/huanshankeji/compose/material3/ext/Button.js.kt index b4181b23..07ea97f2 100644 --- a/compose-multiplatform-material3/src/jsMain/kotlin/com/huanshankeji/compose/material3/ext/Button.js.kt +++ b/compose-multiplatform-material3/src/jsMain/kotlin/com/huanshankeji/compose/material3/ext/Button.js.kt @@ -2,7 +2,7 @@ package com.huanshankeji.compose.material3.ext import androidx.compose.runtime.Composable import com.huanshankeji.compose.html.material3.MdButtonScope -import com.huanshankeji.compose.material3.CommonButton +import com.huanshankeji.compose.material3.* import com.huanshankeji.compose.ui.Modifier @Composable @@ -16,6 +16,50 @@ actual fun Button( ButtonScope(this).content() } +@Composable +actual fun ElevatedButton( + onClick: () -> Unit, + modifier: Modifier, + enabled: Boolean, + content: @Composable ButtonScope.() -> Unit +) = + CommonElevatedButton(onClick, modifier, enabled) { + ButtonScope(this).content() + } + +@Composable +actual fun FilledTonalButton( + onClick: () -> Unit, + modifier: Modifier, + enabled: Boolean, + content: @Composable ButtonScope.() -> Unit +) = + CommonFilledTonalButton(onClick, modifier, enabled) { + ButtonScope(this).content() + } + +@Composable +actual fun OutlinedButton( + onClick: () -> Unit, + modifier: Modifier, + enabled: Boolean, + content: @Composable ButtonScope.() -> Unit +) = + CommonOutlinedButton(onClick, modifier, enabled) { + ButtonScope(this).content() + } + +@Composable +actual fun TextButton( + onClick: () -> Unit, + modifier: Modifier, + enabled: Boolean, + content: @Composable ButtonScope.() -> Unit +) = + CommonTextButton(onClick, modifier, enabled) { + ButtonScope(this).content() + } + actual class ButtonScope(val mdButtonScope: MdButtonScope) { @Composable actual fun Icon() { From 348e801d9f9dd2c6831db3af8dcd11a9c1fcc441 Mon Sep 17 00:00:00 2001 From: Shreck Ye Date: Thu, 25 Apr 2024 15:52:51 +0800 Subject: [PATCH 37/75] Extract common functions and simplify --- .../com/huanshankeji/compose/Enabled.kt | 5 ++ .../build.gradle.kts | 1 + .../material3/Button.androidxCommon.kt | 35 ++++---- .../material3/ext/Button.androidxCommon.kt | 36 ++++---- .../compose/material3/Button.js.kt | 88 +++++++++---------- .../compose/material3/ext/Button.js.kt | 25 +++--- 6 files changed, 100 insertions(+), 90 deletions(-) create mode 100644 compose-multiplatform-common/src/commonMain/kotlin/com/huanshankeji/compose/Enabled.kt diff --git a/compose-multiplatform-common/src/commonMain/kotlin/com/huanshankeji/compose/Enabled.kt b/compose-multiplatform-common/src/commonMain/kotlin/com/huanshankeji/compose/Enabled.kt new file mode 100644 index 00000000..f71054e5 --- /dev/null +++ b/compose-multiplatform-common/src/commonMain/kotlin/com/huanshankeji/compose/Enabled.kt @@ -0,0 +1,5 @@ +package com.huanshankeji.compose + +// consider moving to a "web-common" or "html-common" module +fun Boolean.enabledToNullableDisabled(): Boolean? = + if (this) null else false diff --git a/compose-multiplatform-material3/build.gradle.kts b/compose-multiplatform-material3/build.gradle.kts index 55429431..0c8015ab 100644 --- a/compose-multiplatform-material3/build.gradle.kts +++ b/compose-multiplatform-material3/build.gradle.kts @@ -27,6 +27,7 @@ kotlin { jsMain { dependencies { api("com.huanshankeji:compose-html-material3:${DependencyVersions.huanshankejiComposeHtml}") + implementation("com.huanshankeji:compose-html-common:${DependencyVersions.huanshankejiComposeHtml}") } } } diff --git a/compose-multiplatform-material3/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material3/Button.androidxCommon.kt b/compose-multiplatform-material3/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material3/Button.androidxCommon.kt index af67beca..5d481805 100644 --- a/compose-multiplatform-material3/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material3/Button.androidxCommon.kt +++ b/compose-multiplatform-material3/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material3/Button.androidxCommon.kt @@ -4,6 +4,11 @@ import androidx.compose.runtime.Composable import com.huanshankeji.compose.foundation.layout.RowScope import com.huanshankeji.compose.ui.Modifier +@Composable +private fun (@Composable (RowScope.() -> Unit)).toPlatformContent(): @Composable androidx.compose.foundation.layout.RowScope.() -> Unit = + { RowScope.Impl(this).(this@toPlatformContent)() } + + @Composable actual fun Button( onClick: () -> Unit, @@ -11,9 +16,9 @@ actual fun Button( enabled: Boolean, content: @Composable RowScope.() -> Unit ) = - androidx.compose.material3.Button(onClick, modifier.platformModifier, enabled) { - RowScope.Impl(this).content() - } + androidx.compose.material3.Button( + onClick, modifier.platformModifier, enabled, content = content.toPlatformContent() + ) @Composable actual fun ElevatedButton( @@ -22,9 +27,9 @@ actual fun ElevatedButton( enabled: Boolean, content: @Composable RowScope.() -> Unit ) = - androidx.compose.material3.ElevatedButton(onClick, modifier.platformModifier, enabled) { - RowScope.Impl(this).content() - } + androidx.compose.material3.ElevatedButton( + onClick, modifier.platformModifier, enabled, content = content.toPlatformContent() + ) @Composable actual fun FilledTonalButton( @@ -33,9 +38,9 @@ actual fun FilledTonalButton( enabled: Boolean, content: @Composable RowScope.() -> Unit ) = - androidx.compose.material3.FilledTonalButton(onClick, modifier.platformModifier, enabled) { - RowScope.Impl(this).content() - } + androidx.compose.material3.FilledTonalButton( + onClick, modifier.platformModifier, enabled, content = content.toPlatformContent() + ) @Composable actual fun OutlinedButton( @@ -44,9 +49,9 @@ actual fun OutlinedButton( enabled: Boolean, content: @Composable RowScope.() -> Unit ) = - androidx.compose.material3.OutlinedButton(onClick, modifier.platformModifier, enabled) { - RowScope.Impl(this).content() - } + androidx.compose.material3.OutlinedButton( + onClick, modifier.platformModifier, enabled, content = content.toPlatformContent() + ) @Composable actual fun TextButton( @@ -55,6 +60,6 @@ actual fun TextButton( enabled: Boolean, content: @Composable RowScope.() -> Unit ) = - androidx.compose.material3.TextButton(onClick, modifier.platformModifier, enabled) { - RowScope.Impl(this).content() - } + androidx.compose.material3.TextButton( + onClick, modifier.platformModifier, enabled, content = content.toPlatformContent() + ) diff --git a/compose-multiplatform-material3/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material3/ext/Button.androidxCommon.kt b/compose-multiplatform-material3/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material3/ext/Button.androidxCommon.kt index 49f37fd9..4317d543 100644 --- a/compose-multiplatform-material3/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material3/ext/Button.androidxCommon.kt +++ b/compose-multiplatform-material3/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material3/ext/Button.androidxCommon.kt @@ -1,8 +1,14 @@ package com.huanshankeji.compose.material3.ext +import androidx.compose.foundation.layout.RowScope import androidx.compose.runtime.Composable import com.huanshankeji.compose.ui.Modifier +@Composable +private fun (@Composable (ButtonScope.() -> Unit)).toButtonScopeContent(): @Composable RowScope.() -> Unit = + { ButtonScope.(this@toButtonScopeContent)() } + + @Composable actual fun Button( onClick: () -> Unit, @@ -10,9 +16,9 @@ actual fun Button( enabled: Boolean, content: @Composable ButtonScope.() -> Unit ) = - androidx.compose.material3.Button(onClick, modifier.platformModifier, enabled) { - ButtonScope.content() - } + androidx.compose.material3.Button( + onClick, modifier.platformModifier, enabled, content = content.toButtonScopeContent() + ) @Composable actual fun ElevatedButton( @@ -20,9 +26,9 @@ actual fun ElevatedButton( modifier: Modifier, enabled: Boolean, content: @Composable ButtonScope.() -> Unit -) = androidx.compose.material3.ElevatedButton(onClick, modifier.platformModifier, enabled) { - ButtonScope.content() -} +) = androidx.compose.material3.ElevatedButton( + onClick, modifier.platformModifier, enabled, content = content.toButtonScopeContent() +) @Composable actual fun FilledTonalButton( @@ -31,9 +37,9 @@ actual fun FilledTonalButton( enabled: Boolean, content: @Composable ButtonScope.() -> Unit ) = - androidx.compose.material3.FilledTonalButton(onClick, modifier.platformModifier, enabled) { - ButtonScope.content() - } + androidx.compose.material3.FilledTonalButton( + onClick, modifier.platformModifier, enabled, content = content.toButtonScopeContent() + ) @Composable actual fun OutlinedButton( @@ -42,9 +48,9 @@ actual fun OutlinedButton( enabled: Boolean, content: @Composable ButtonScope.() -> Unit ) = - androidx.compose.material3.OutlinedButton(onClick, modifier.platformModifier, enabled) { - ButtonScope.content() - } + androidx.compose.material3.OutlinedButton( + onClick, modifier.platformModifier, enabled, content = content.toButtonScopeContent() + ) @Composable actual fun TextButton( @@ -53,9 +59,9 @@ actual fun TextButton( enabled: Boolean, content: @Composable ButtonScope.() -> Unit ) = - androidx.compose.material3.TextButton(onClick, modifier.platformModifier, enabled) { - ButtonScope.content() - } + androidx.compose.material3.TextButton( + onClick, modifier.platformModifier, enabled, content = content.toButtonScopeContent() + ) actual object ButtonScope { @Composable diff --git a/compose-multiplatform-material3/src/jsMain/kotlin/com/huanshankeji/compose/material3/Button.js.kt b/compose-multiplatform-material3/src/jsMain/kotlin/com/huanshankeji/compose/material3/Button.js.kt index 46d18791..d4d9d36f 100644 --- a/compose-multiplatform-material3/src/jsMain/kotlin/com/huanshankeji/compose/material3/Button.js.kt +++ b/compose-multiplatform-material3/src/jsMain/kotlin/com/huanshankeji/compose/material3/Button.js.kt @@ -1,11 +1,24 @@ package com.huanshankeji.compose.material3 import androidx.compose.runtime.Composable +import com.huanshankeji.compose.enabledToNullableDisabled import com.huanshankeji.compose.foundation.layout.Row import com.huanshankeji.compose.foundation.layout.RowScope import com.huanshankeji.compose.html.material3.* import com.huanshankeji.compose.ui.Modifier +import com.huanshankeji.compose.web.attributes.Attrs import com.varabyte.kobweb.compose.ui.toAttrs +import org.w3c.dom.HTMLElement + +private fun Modifier.toButtonAttrs(onClick: () -> Unit): Attrs = + platformModifier.toAttrs { + onClick { onClick() } + } + +@Composable +private fun (@Composable (RowScope.() -> Unit)).toMdButtonScopeContent(): @Composable MdButtonScope.() -> Unit = + { Row(content = this@toMdButtonScopeContent) } + @Composable internal fun CommonButton( @@ -14,12 +27,11 @@ internal fun CommonButton( enabled: Boolean, content: @Composable MdButtonScope.() -> Unit ) = - MdFilledButton(disabled = if (enabled) null else true, - attrs = modifier.platformModifier.toAttrs { - onClick { onClick() } - }) { - content() - } + MdFilledButton( + disabled = enabled.enabledToNullableDisabled(), + attrs = modifier.toButtonAttrs(onClick), + content = content + ) @Composable actual fun Button( @@ -28,9 +40,7 @@ actual fun Button( enabled: Boolean, content: @Composable RowScope.() -> Unit ) = - CommonButton(onClick, modifier, enabled) { - Row(content = content) - } + CommonButton(onClick, modifier, enabled, content.toMdButtonScopeContent()) @Composable internal fun CommonElevatedButton( @@ -39,12 +49,11 @@ internal fun CommonElevatedButton( enabled: Boolean, content: @Composable MdButtonScope.() -> Unit ) = - MdElevatedButton(disabled = if (enabled) null else true, - attrs = modifier.platformModifier.toAttrs { - onClick { onClick() } - }) { - content() - } + MdElevatedButton( + disabled = enabled.enabledToNullableDisabled(), + attrs = modifier.toButtonAttrs(onClick), + content = content + ) @Composable actual fun ElevatedButton( @@ -53,9 +62,7 @@ actual fun ElevatedButton( enabled: Boolean, content: @Composable RowScope.() -> Unit ) = - CommonElevatedButton(onClick, modifier, enabled) { - Row(content = content) - } + CommonElevatedButton(onClick, modifier, enabled, content.toMdButtonScopeContent()) @Composable internal fun CommonFilledTonalButton( @@ -64,12 +71,11 @@ internal fun CommonFilledTonalButton( enabled: Boolean, content: @Composable MdButtonScope.() -> Unit ) = - MdFilledTonalButton(disabled = if (enabled) null else true, - attrs = modifier.platformModifier.toAttrs { - onClick { onClick() } - }) { - content() - } + MdFilledTonalButton( + disabled = enabled.enabledToNullableDisabled(), + attrs = modifier.toButtonAttrs(onClick), + content = content + ) @Composable actual fun FilledTonalButton( @@ -78,9 +84,7 @@ actual fun FilledTonalButton( enabled: Boolean, content: @Composable RowScope.() -> Unit ) = - CommonFilledTonalButton(onClick, modifier, enabled) { - Row(content = content) - } + CommonFilledTonalButton(onClick, modifier, enabled, content.toMdButtonScopeContent()) @Composable internal fun CommonOutlinedButton( @@ -89,12 +93,11 @@ internal fun CommonOutlinedButton( enabled: Boolean, content: @Composable MdButtonScope.() -> Unit ) = - MdOutlinedButton(disabled = if (enabled) null else true, - attrs = modifier.platformModifier.toAttrs { - onClick { onClick() } - }) { - content() - } + MdOutlinedButton( + disabled = enabled.enabledToNullableDisabled(), + attrs = modifier.toButtonAttrs(onClick), + content = content + ) @Composable actual fun OutlinedButton( @@ -103,9 +106,7 @@ actual fun OutlinedButton( enabled: Boolean, content: @Composable RowScope.() -> Unit ) = - CommonOutlinedButton(onClick, modifier, enabled) { - Row(content = content) - } + CommonOutlinedButton(onClick, modifier, enabled, content.toMdButtonScopeContent()) @Composable internal fun CommonTextButton( @@ -114,12 +115,11 @@ internal fun CommonTextButton( enabled: Boolean, content: @Composable MdButtonScope.() -> Unit ) = - MdTextButton(disabled = if (enabled) null else true, - attrs = modifier.platformModifier.toAttrs { - onClick { onClick() } - }) { - content() - } + MdTextButton( + disabled = enabled.enabledToNullableDisabled(), + attrs = modifier.toButtonAttrs(onClick), + content = content + ) @Composable actual fun TextButton( @@ -128,6 +128,4 @@ actual fun TextButton( enabled: Boolean, content: @Composable RowScope.() -> Unit ) = - CommonTextButton(onClick, modifier, enabled) { - Row(content = content) - } + CommonTextButton(onClick, modifier, enabled, content.toMdButtonScopeContent()) diff --git a/compose-multiplatform-material3/src/jsMain/kotlin/com/huanshankeji/compose/material3/ext/Button.js.kt b/compose-multiplatform-material3/src/jsMain/kotlin/com/huanshankeji/compose/material3/ext/Button.js.kt index 07ea97f2..b390c692 100644 --- a/compose-multiplatform-material3/src/jsMain/kotlin/com/huanshankeji/compose/material3/ext/Button.js.kt +++ b/compose-multiplatform-material3/src/jsMain/kotlin/com/huanshankeji/compose/material3/ext/Button.js.kt @@ -5,6 +5,11 @@ import com.huanshankeji.compose.html.material3.MdButtonScope import com.huanshankeji.compose.material3.* import com.huanshankeji.compose.ui.Modifier +@Composable +private fun (@Composable (ButtonScope.() -> Unit)).toMdButtonScopeContent(): @Composable MdButtonScope.() -> Unit = + { ButtonScope(this).(this@toMdButtonScopeContent)() } + + @Composable actual fun Button( onClick: () -> Unit, @@ -12,9 +17,7 @@ actual fun Button( enabled: Boolean, content: @Composable ButtonScope.() -> Unit ) = - CommonButton(onClick, modifier, enabled) { - ButtonScope(this).content() - } + CommonButton(onClick, modifier, enabled, content.toMdButtonScopeContent()) @Composable actual fun ElevatedButton( @@ -23,9 +26,7 @@ actual fun ElevatedButton( enabled: Boolean, content: @Composable ButtonScope.() -> Unit ) = - CommonElevatedButton(onClick, modifier, enabled) { - ButtonScope(this).content() - } + CommonElevatedButton(onClick, modifier, enabled, content.toMdButtonScopeContent()) @Composable actual fun FilledTonalButton( @@ -34,9 +35,7 @@ actual fun FilledTonalButton( enabled: Boolean, content: @Composable ButtonScope.() -> Unit ) = - CommonFilledTonalButton(onClick, modifier, enabled) { - ButtonScope(this).content() - } + CommonFilledTonalButton(onClick, modifier, enabled, content.toMdButtonScopeContent()) @Composable actual fun OutlinedButton( @@ -45,9 +44,7 @@ actual fun OutlinedButton( enabled: Boolean, content: @Composable ButtonScope.() -> Unit ) = - CommonOutlinedButton(onClick, modifier, enabled) { - ButtonScope(this).content() - } + CommonOutlinedButton(onClick, modifier, enabled, content.toMdButtonScopeContent()) @Composable actual fun TextButton( @@ -56,9 +53,7 @@ actual fun TextButton( enabled: Boolean, content: @Composable ButtonScope.() -> Unit ) = - CommonTextButton(onClick, modifier, enabled) { - ButtonScope(this).content() - } + CommonTextButton(onClick, modifier, enabled, content.toMdButtonScopeContent()) actual class ButtonScope(val mdButtonScope: MdButtonScope) { @Composable From 7c5bc3deb220d60893063c943bc5855ec4cbd592 Mon Sep 17 00:00:00 2001 From: Shreck Ye Date: Thu, 25 Apr 2024 18:49:46 +0800 Subject: [PATCH 38/75] Show and test all the Material 3 buttons in the `Material3` composable in the demo A corresponding commit: https://github.com/huanshankeji/compose-html-material/commit/938bf850682974ef6bf7542ea268f6b8b3518166 --- .../compose/material/demo/Material2.kt | 9 +----- .../compose/material/demo/Material3.kt | 28 +++++++++++++++++-- 2 files changed, 26 insertions(+), 11 deletions(-) diff --git a/demo/src/commonMain/kotlin/com/huanshankeji/compose/material/demo/Material2.kt b/demo/src/commonMain/kotlin/com/huanshankeji/compose/material/demo/Material2.kt index a91f9ae2..22b9964a 100644 --- a/demo/src/commonMain/kotlin/com/huanshankeji/compose/material/demo/Material2.kt +++ b/demo/src/commonMain/kotlin/com/huanshankeji/compose/material/demo/Material2.kt @@ -25,8 +25,6 @@ import com.huanshankeji.compose.material.lazy.ext.LazyColumn import com.huanshankeji.compose.ui.Modifier import com.huanshankeji.compose.ui.graphics.Color import com.huanshankeji.compose.material.ext.Button as ExtButton -import com.huanshankeji.compose.material3.Button as M3Button -import com.huanshankeji.compose.material3.ext.Button as M3ExtButton @Composable fun Material2() { @@ -43,9 +41,8 @@ fun Material2() { var count by remember { mutableStateOf(0) } val onClick: () -> Unit = { count++ } - val buttonContent: @Composable () -> Unit = { - Text(count.toString()) // TODO use `com.huanshankeji.compose.material(3).ext.InlineText` + InlineText(count.toString()) } val rowScopeButtonContent: @Composable RowScope.() -> Unit = { buttonContent() } @@ -58,10 +55,6 @@ fun Material2() { } IconButton(onClick, icon = Icons.Default.Add, contentDescription = "increment count") } - Row { - M3Button(onClick, content = rowScopeButtonContent) - M3ExtButton(onClick) { buttonContent() } - } Box(Modifier.padding(16.dp)) { LazyColumn(Modifier.height(100.dp)) { diff --git a/demo/src/commonMain/kotlin/com/huanshankeji/compose/material/demo/Material3.kt b/demo/src/commonMain/kotlin/com/huanshankeji/compose/material/demo/Material3.kt index c70f71eb..bf77cf9a 100644 --- a/demo/src/commonMain/kotlin/com/huanshankeji/compose/material/demo/Material3.kt +++ b/demo/src/commonMain/kotlin/com/huanshankeji/compose/material/demo/Material3.kt @@ -1,8 +1,30 @@ package com.huanshankeji.compose.material.demo -import androidx.compose.runtime.Composable +import androidx.compose.runtime.* +import com.huanshankeji.compose.foundation.layout.Column +import com.huanshankeji.compose.foundation.layout.Row +import com.huanshankeji.compose.foundation.layout.RowScope +import com.huanshankeji.compose.material.Text +import com.huanshankeji.compose.material3.ext.* +import com.huanshankeji.compose.material3.Button as RowScopeButton @Composable fun Material3() { - Material2() // TODO -} \ No newline at end of file + Column { + var count by remember { mutableStateOf(0) } + val onClick: () -> Unit = { count++ } + val buttonContent: @Composable () -> Unit = { + Text(count.toString()) // TODO use `com.huanshankeji.compose.material3.ext.InlineText` + } + val rowScopeButtonContent: @Composable RowScope.() -> Unit = { buttonContent() } + val buttonScopeButtonContent: @Composable ButtonScope.() -> Unit = { buttonContent() } + Row { + RowScopeButton(onClick, content = rowScopeButtonContent) + Button(onClick, content = buttonScopeButtonContent) + ElevatedButton(onClick, content = buttonScopeButtonContent) + FilledTonalButton(onClick, content = buttonScopeButtonContent) + OutlinedButton(onClick, content = buttonScopeButtonContent) + TextButton(onClick, content = buttonScopeButtonContent) + } + } +} From 6f6260cb27ebc389f2459332ce9cbb085558912f Mon Sep 17 00:00:00 2001 From: Shreck Ye Date: Thu, 25 Apr 2024 22:40:35 +0800 Subject: [PATCH 39/75] Add the Material 3 `Checkbox` composable and show and test it in the demo A corresponding commit: https://github.com/huanshankeji/compose-html-material/commit/07c939e4a2e020ef5dbf4e36101177894db1d581 --- .../material3/Checkbox.androidxCommon.kt | 13 ++++++++++ .../compose/material3/Checkbox.kt | 12 ++++++++++ .../compose/material3/Checkbox.js.kt | 24 +++++++++++++++++++ .../compose/material/demo/Material3.kt | 11 +++++++-- 4 files changed, 58 insertions(+), 2 deletions(-) create mode 100644 compose-multiplatform-material3/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material3/Checkbox.androidxCommon.kt create mode 100644 compose-multiplatform-material3/src/commonMain/kotlin/com/huanshankeji/compose/material3/Checkbox.kt create mode 100644 compose-multiplatform-material3/src/jsMain/kotlin/com/huanshankeji/compose/material3/Checkbox.js.kt diff --git a/compose-multiplatform-material3/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material3/Checkbox.androidxCommon.kt b/compose-multiplatform-material3/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material3/Checkbox.androidxCommon.kt new file mode 100644 index 00000000..423267a6 --- /dev/null +++ b/compose-multiplatform-material3/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material3/Checkbox.androidxCommon.kt @@ -0,0 +1,13 @@ +package com.huanshankeji.compose.material3 + +import androidx.compose.runtime.Composable +import com.huanshankeji.compose.ui.Modifier + +@Composable +actual fun Checkbox( + checked: Boolean, + onCheckedChange: ((Boolean) -> Unit)?, + modifier: Modifier, + enabled: Boolean +) = + androidx.compose.material3.Checkbox(checked, onCheckedChange, modifier.platformModifier, enabled) diff --git a/compose-multiplatform-material3/src/commonMain/kotlin/com/huanshankeji/compose/material3/Checkbox.kt b/compose-multiplatform-material3/src/commonMain/kotlin/com/huanshankeji/compose/material3/Checkbox.kt new file mode 100644 index 00000000..220f5506 --- /dev/null +++ b/compose-multiplatform-material3/src/commonMain/kotlin/com/huanshankeji/compose/material3/Checkbox.kt @@ -0,0 +1,12 @@ +package com.huanshankeji.compose.material3 + +import androidx.compose.runtime.Composable +import com.huanshankeji.compose.ui.Modifier + +@Composable +expect fun Checkbox( + checked: Boolean, + onCheckedChange: ((Boolean) -> Unit)?, + modifier: Modifier = Modifier, + enabled: Boolean = true +) diff --git a/compose-multiplatform-material3/src/jsMain/kotlin/com/huanshankeji/compose/material3/Checkbox.js.kt b/compose-multiplatform-material3/src/jsMain/kotlin/com/huanshankeji/compose/material3/Checkbox.js.kt new file mode 100644 index 00000000..f6bd6fe3 --- /dev/null +++ b/compose-multiplatform-material3/src/jsMain/kotlin/com/huanshankeji/compose/material3/Checkbox.js.kt @@ -0,0 +1,24 @@ +package com.huanshankeji.compose.material3 + +import androidx.compose.runtime.Composable +import com.huanshankeji.compose.enabledToNullableDisabled +import com.huanshankeji.compose.html.material3.MdCheckbox +import com.huanshankeji.compose.html.material3.MdCheckboxState +import com.huanshankeji.compose.ui.Modifier +import com.varabyte.kobweb.compose.ui.toAttrs + +@Composable +actual fun Checkbox( + checked: Boolean, + onCheckedChange: ((Boolean) -> Unit)?, + modifier: Modifier, + enabled: Boolean +) = + MdCheckbox( + if (checked) MdCheckboxState.Checked else MdCheckboxState.Unchecked, + enabled.enabledToNullableDisabled(), + attrs = modifier.platformModifier.toAttrs { + onCheckedChange?.let { onClick { it(!checked) } } + //onCheckedChange?.let { onInput { it(!checked) } } + } + ) diff --git a/demo/src/commonMain/kotlin/com/huanshankeji/compose/material/demo/Material3.kt b/demo/src/commonMain/kotlin/com/huanshankeji/compose/material/demo/Material3.kt index bf77cf9a..d8b0d101 100644 --- a/demo/src/commonMain/kotlin/com/huanshankeji/compose/material/demo/Material3.kt +++ b/demo/src/commonMain/kotlin/com/huanshankeji/compose/material/demo/Material3.kt @@ -4,7 +4,8 @@ import androidx.compose.runtime.* import com.huanshankeji.compose.foundation.layout.Column import com.huanshankeji.compose.foundation.layout.Row import com.huanshankeji.compose.foundation.layout.RowScope -import com.huanshankeji.compose.material.Text +import com.huanshankeji.compose.foundation.text.ext.InlineBasicText +import com.huanshankeji.compose.material3.Checkbox import com.huanshankeji.compose.material3.ext.* import com.huanshankeji.compose.material3.Button as RowScopeButton @@ -14,7 +15,7 @@ fun Material3() { var count by remember { mutableStateOf(0) } val onClick: () -> Unit = { count++ } val buttonContent: @Composable () -> Unit = { - Text(count.toString()) // TODO use `com.huanshankeji.compose.material3.ext.InlineText` + InlineBasicText(count.toString()) // TODO use `com.huanshankeji.compose.material3.ext.InlineText` } val rowScopeButtonContent: @Composable RowScope.() -> Unit = { buttonContent() } val buttonScopeButtonContent: @Composable ButtonScope.() -> Unit = { buttonContent() } @@ -26,5 +27,11 @@ fun Material3() { OutlinedButton(onClick, content = buttonScopeButtonContent) TextButton(onClick, content = buttonScopeButtonContent) } + + Row { + var checked by remember { mutableStateOf(false) } + Checkbox(checked, { checked = it }) + Checkbox(checked, { checked = it }) + } } } From 5da5e406a15c28ea54c0abc7e8e09c972482e128 Mon Sep 17 00:00:00 2001 From: Shreck Ye Date: Sat, 27 Apr 2024 17:56:41 +0800 Subject: [PATCH 40/75] Add the Material 3 `Switch` composable and show and test it in the demo, use the attribute conversion functions for `Boolean`, and use the newly added `onInput` The original Compose HTML `onInput` can't be invoked on an `AttrScope` of an `HTMLElement` that's not an `HTMLInputElement` and there seems to be no way to add a one with `registerEventListener` because `SyntheticEventListener` has an internal constructor and its implementations are internal too. A corresponding commit: https://github.com/huanshankeji/compose-html-material/commit/64de220b52870493d66c4fddb967b7684eae1ea1 --- .../com/huanshankeji/compose/Enabled.kt | 5 ---- .../material3/Switch.androidxCommon.kt | 13 +++++++++++ .../huanshankeji/compose/material3/Switch.kt | 12 ++++++++++ .../compose/material3/ext/Switch.kt | 3 +++ .../compose/material3/Button.js.kt | 12 +++++----- .../compose/material3/Checkbox.js.kt | 8 +++---- .../compose/material3/Switch.js.kt | 23 +++++++++++++++++++ .../compose/material/demo/Material3.kt | 3 ++- 8 files changed, 63 insertions(+), 16 deletions(-) delete mode 100644 compose-multiplatform-common/src/commonMain/kotlin/com/huanshankeji/compose/Enabled.kt create mode 100644 compose-multiplatform-material3/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material3/Switch.androidxCommon.kt create mode 100644 compose-multiplatform-material3/src/commonMain/kotlin/com/huanshankeji/compose/material3/Switch.kt create mode 100644 compose-multiplatform-material3/src/commonMain/kotlin/com/huanshankeji/compose/material3/ext/Switch.kt create mode 100644 compose-multiplatform-material3/src/jsMain/kotlin/com/huanshankeji/compose/material3/Switch.js.kt diff --git a/compose-multiplatform-common/src/commonMain/kotlin/com/huanshankeji/compose/Enabled.kt b/compose-multiplatform-common/src/commonMain/kotlin/com/huanshankeji/compose/Enabled.kt deleted file mode 100644 index f71054e5..00000000 --- a/compose-multiplatform-common/src/commonMain/kotlin/com/huanshankeji/compose/Enabled.kt +++ /dev/null @@ -1,5 +0,0 @@ -package com.huanshankeji.compose - -// consider moving to a "web-common" or "html-common" module -fun Boolean.enabledToNullableDisabled(): Boolean? = - if (this) null else false diff --git a/compose-multiplatform-material3/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material3/Switch.androidxCommon.kt b/compose-multiplatform-material3/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material3/Switch.androidxCommon.kt new file mode 100644 index 00000000..7fc78321 --- /dev/null +++ b/compose-multiplatform-material3/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material3/Switch.androidxCommon.kt @@ -0,0 +1,13 @@ +package com.huanshankeji.compose.material3 + +import androidx.compose.runtime.Composable +import com.huanshankeji.compose.ui.Modifier + +@Composable +actual fun Switch( + checked: Boolean, + onCheckedChange: ((Boolean) -> Unit)?, + modifier: Modifier, + enabled: Boolean +) = + androidx.compose.material3.Switch(checked, onCheckedChange, modifier.platformModifier, enabled = enabled) diff --git a/compose-multiplatform-material3/src/commonMain/kotlin/com/huanshankeji/compose/material3/Switch.kt b/compose-multiplatform-material3/src/commonMain/kotlin/com/huanshankeji/compose/material3/Switch.kt new file mode 100644 index 00000000..0aec1974 --- /dev/null +++ b/compose-multiplatform-material3/src/commonMain/kotlin/com/huanshankeji/compose/material3/Switch.kt @@ -0,0 +1,12 @@ +package com.huanshankeji.compose.material3 + +import androidx.compose.runtime.Composable +import com.huanshankeji.compose.ui.Modifier + +@Composable +expect fun Switch( + checked: Boolean, + onCheckedChange: ((Boolean) -> Unit)?, + modifier: Modifier = Modifier, + enabled: Boolean = true +) diff --git a/compose-multiplatform-material3/src/commonMain/kotlin/com/huanshankeji/compose/material3/ext/Switch.kt b/compose-multiplatform-material3/src/commonMain/kotlin/com/huanshankeji/compose/material3/ext/Switch.kt new file mode 100644 index 00000000..759f21c5 --- /dev/null +++ b/compose-multiplatform-material3/src/commonMain/kotlin/com/huanshankeji/compose/material3/ext/Switch.kt @@ -0,0 +1,3 @@ +package com.huanshankeji.compose.material3.ext + +// LabelWithSwitch diff --git a/compose-multiplatform-material3/src/jsMain/kotlin/com/huanshankeji/compose/material3/Button.js.kt b/compose-multiplatform-material3/src/jsMain/kotlin/com/huanshankeji/compose/material3/Button.js.kt index d4d9d36f..b3de33f9 100644 --- a/compose-multiplatform-material3/src/jsMain/kotlin/com/huanshankeji/compose/material3/Button.js.kt +++ b/compose-multiplatform-material3/src/jsMain/kotlin/com/huanshankeji/compose/material3/Button.js.kt @@ -1,12 +1,12 @@ package com.huanshankeji.compose.material3 import androidx.compose.runtime.Composable -import com.huanshankeji.compose.enabledToNullableDisabled import com.huanshankeji.compose.foundation.layout.Row import com.huanshankeji.compose.foundation.layout.RowScope import com.huanshankeji.compose.html.material3.* import com.huanshankeji.compose.ui.Modifier import com.huanshankeji.compose.web.attributes.Attrs +import com.huanshankeji.compose.web.attributes.isFalseOrNull import com.varabyte.kobweb.compose.ui.toAttrs import org.w3c.dom.HTMLElement @@ -28,7 +28,7 @@ internal fun CommonButton( content: @Composable MdButtonScope.() -> Unit ) = MdFilledButton( - disabled = enabled.enabledToNullableDisabled(), + disabled = enabled.isFalseOrNull(), attrs = modifier.toButtonAttrs(onClick), content = content ) @@ -50,7 +50,7 @@ internal fun CommonElevatedButton( content: @Composable MdButtonScope.() -> Unit ) = MdElevatedButton( - disabled = enabled.enabledToNullableDisabled(), + disabled = enabled.isFalseOrNull(), attrs = modifier.toButtonAttrs(onClick), content = content ) @@ -72,7 +72,7 @@ internal fun CommonFilledTonalButton( content: @Composable MdButtonScope.() -> Unit ) = MdFilledTonalButton( - disabled = enabled.enabledToNullableDisabled(), + disabled = enabled.isFalseOrNull(), attrs = modifier.toButtonAttrs(onClick), content = content ) @@ -94,7 +94,7 @@ internal fun CommonOutlinedButton( content: @Composable MdButtonScope.() -> Unit ) = MdOutlinedButton( - disabled = enabled.enabledToNullableDisabled(), + disabled = enabled.isFalseOrNull(), attrs = modifier.toButtonAttrs(onClick), content = content ) @@ -116,7 +116,7 @@ internal fun CommonTextButton( content: @Composable MdButtonScope.() -> Unit ) = MdTextButton( - disabled = enabled.enabledToNullableDisabled(), + disabled = enabled.isFalseOrNull(), attrs = modifier.toButtonAttrs(onClick), content = content ) diff --git a/compose-multiplatform-material3/src/jsMain/kotlin/com/huanshankeji/compose/material3/Checkbox.js.kt b/compose-multiplatform-material3/src/jsMain/kotlin/com/huanshankeji/compose/material3/Checkbox.js.kt index f6bd6fe3..dae58a7a 100644 --- a/compose-multiplatform-material3/src/jsMain/kotlin/com/huanshankeji/compose/material3/Checkbox.js.kt +++ b/compose-multiplatform-material3/src/jsMain/kotlin/com/huanshankeji/compose/material3/Checkbox.js.kt @@ -1,10 +1,10 @@ package com.huanshankeji.compose.material3 import androidx.compose.runtime.Composable -import com.huanshankeji.compose.enabledToNullableDisabled import com.huanshankeji.compose.html.material3.MdCheckbox -import com.huanshankeji.compose.html.material3.MdCheckboxState import com.huanshankeji.compose.ui.Modifier +import com.huanshankeji.compose.web.attributes.isFalseOrNull +import com.huanshankeji.compose.web.attributes.isTrueOrNull import com.varabyte.kobweb.compose.ui.toAttrs @Composable @@ -15,8 +15,8 @@ actual fun Checkbox( enabled: Boolean ) = MdCheckbox( - if (checked) MdCheckboxState.Checked else MdCheckboxState.Unchecked, - enabled.enabledToNullableDisabled(), + checked.isTrueOrNull(), + enabled.isFalseOrNull(), attrs = modifier.platformModifier.toAttrs { onCheckedChange?.let { onClick { it(!checked) } } //onCheckedChange?.let { onInput { it(!checked) } } diff --git a/compose-multiplatform-material3/src/jsMain/kotlin/com/huanshankeji/compose/material3/Switch.js.kt b/compose-multiplatform-material3/src/jsMain/kotlin/com/huanshankeji/compose/material3/Switch.js.kt new file mode 100644 index 00000000..a0481230 --- /dev/null +++ b/compose-multiplatform-material3/src/jsMain/kotlin/com/huanshankeji/compose/material3/Switch.js.kt @@ -0,0 +1,23 @@ +package com.huanshankeji.compose.material3 + +import androidx.compose.runtime.Composable +import com.huanshankeji.compose.html.material3.MdSwitch +import com.huanshankeji.compose.ui.Modifier +import com.huanshankeji.compose.web.attributes.isFalseOrNull +import com.huanshankeji.compose.web.attributes.isTrueOrNull +import com.huanshankeji.compose.web.attributes.onInput +import com.varabyte.kobweb.compose.ui.toAttrs + +@Composable +actual fun Switch( + checked: Boolean, + onCheckedChange: ((Boolean) -> Unit)?, + modifier: Modifier, + enabled: Boolean +) = + MdSwitch( + enabled.isFalseOrNull(), + checked.isTrueOrNull(), + attrs = modifier.platformModifier.toAttrs { + onCheckedChange?.let { onInput { onCheckedChange(!checked) } } + }) diff --git a/demo/src/commonMain/kotlin/com/huanshankeji/compose/material/demo/Material3.kt b/demo/src/commonMain/kotlin/com/huanshankeji/compose/material/demo/Material3.kt index d8b0d101..ffe81391 100644 --- a/demo/src/commonMain/kotlin/com/huanshankeji/compose/material/demo/Material3.kt +++ b/demo/src/commonMain/kotlin/com/huanshankeji/compose/material/demo/Material3.kt @@ -6,6 +6,7 @@ import com.huanshankeji.compose.foundation.layout.Row import com.huanshankeji.compose.foundation.layout.RowScope import com.huanshankeji.compose.foundation.text.ext.InlineBasicText import com.huanshankeji.compose.material3.Checkbox +import com.huanshankeji.compose.material3.Switch import com.huanshankeji.compose.material3.ext.* import com.huanshankeji.compose.material3.Button as RowScopeButton @@ -31,7 +32,7 @@ fun Material3() { Row { var checked by remember { mutableStateOf(false) } Checkbox(checked, { checked = it }) - Checkbox(checked, { checked = it }) + Switch(checked, { checked = it }) } } } From 1a00d0e0c308f1910edd45ef59d6b08b15042165 Mon Sep 17 00:00:00 2001 From: Shreck Ye Date: Sat, 27 Apr 2024 18:59:29 +0800 Subject: [PATCH 41/75] Use `onInput` for the Material 3 `Checkbox` on JS --- .../com/huanshankeji/compose/material3/Checkbox.js.kt | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/compose-multiplatform-material3/src/jsMain/kotlin/com/huanshankeji/compose/material3/Checkbox.js.kt b/compose-multiplatform-material3/src/jsMain/kotlin/com/huanshankeji/compose/material3/Checkbox.js.kt index dae58a7a..e1b3e232 100644 --- a/compose-multiplatform-material3/src/jsMain/kotlin/com/huanshankeji/compose/material3/Checkbox.js.kt +++ b/compose-multiplatform-material3/src/jsMain/kotlin/com/huanshankeji/compose/material3/Checkbox.js.kt @@ -5,6 +5,7 @@ import com.huanshankeji.compose.html.material3.MdCheckbox import com.huanshankeji.compose.ui.Modifier import com.huanshankeji.compose.web.attributes.isFalseOrNull import com.huanshankeji.compose.web.attributes.isTrueOrNull +import com.huanshankeji.compose.web.attributes.onInput import com.varabyte.kobweb.compose.ui.toAttrs @Composable @@ -18,7 +19,12 @@ actual fun Checkbox( checked.isTrueOrNull(), enabled.isFalseOrNull(), attrs = modifier.platformModifier.toAttrs { - onCheckedChange?.let { onClick { it(!checked) } } - //onCheckedChange?.let { onInput { it(!checked) } } + /* + Use `onInput` here because it wraps an `input` element. + Also see: https://stackoverflow.com/questions/58016503/click-vs-input-vs-change-for-checkboxes + */ + + //onCheckedChange?.let { onClick { it(!checked) } } + onCheckedChange?.let { onInput { it(!checked) } } } ) From c5fce3b217cf01c82f03d0bbb4ce218846d5751c Mon Sep 17 00:00:00 2001 From: Shreck Ye Date: Sun, 28 Apr 2024 22:49:45 +0800 Subject: [PATCH 42/75] Add the `TextField` composables and show and test them in the demo There is a bug that if you edit one composable and then another they are out of sync. The corresponding commit: https://github.com/huanshankeji/compose-html-material/commit/a91b0b2f39c039a8635a56995e8f518072ec0941 --- .../material3/ext/TextField.androidxCommon.kt | 83 ++++++++++++++ .../compose/material3/ext/TextField.kt | 49 ++++++++ .../compose/material3/ext/TextField.js.kt | 107 ++++++++++++++++++ .../compose/material/demo/Material3.kt | 4 + 4 files changed, 243 insertions(+) create mode 100644 compose-multiplatform-material3/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material3/ext/TextField.androidxCommon.kt create mode 100644 compose-multiplatform-material3/src/commonMain/kotlin/com/huanshankeji/compose/material3/ext/TextField.kt create mode 100644 compose-multiplatform-material3/src/jsMain/kotlin/com/huanshankeji/compose/material3/ext/TextField.js.kt diff --git a/compose-multiplatform-material3/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material3/ext/TextField.androidxCommon.kt b/compose-multiplatform-material3/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material3/ext/TextField.androidxCommon.kt new file mode 100644 index 00000000..bcec783b --- /dev/null +++ b/compose-multiplatform-material3/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material3/ext/TextField.androidxCommon.kt @@ -0,0 +1,83 @@ +package com.huanshankeji.compose.material3.ext + +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import com.huanshankeji.compose.ui.Modifier + +// This function can be moved into a common file. +fun String?.ToNullableTextComposable(): (@Composable () -> Unit)? = + this?.let { { Text(it) } } + +@Composable +actual fun TextField( + value: String, + onValueChange: (String) -> Unit, + modifier: Modifier, + enabled: Boolean, + readOnly: Boolean, + label: String?, + placeholder: String?, + leadingIcon: @Composable (() -> Unit)?, + trailingIcon: @Composable (() -> Unit)?, + prefix: String?, + suffix: String?, + supportingText: String?, + isError: Boolean, + singleLine: Boolean, + lines: Int +) = + androidx.compose.material3.TextField( + value, + onValueChange, + modifier.platformModifier, + enabled, + readOnly, + label = label.ToNullableTextComposable(), + placeholder = placeholder.ToNullableTextComposable(), + leadingIcon = leadingIcon, + trailingIcon = trailingIcon, + prefix = prefix.ToNullableTextComposable(), + suffix = suffix.ToNullableTextComposable(), + supportingText = supportingText.ToNullableTextComposable(), + isError = isError, + singleLine = singleLine, + maxLines = lines, + minLines = lines + ) + +@Composable +actual fun OutlinedTextField( + value: String, + onValueChange: (String) -> Unit, + modifier: Modifier, + enabled: Boolean, + readOnly: Boolean, + label: String?, + placeholder: String?, + leadingIcon: @Composable (() -> Unit)?, + trailingIcon: @Composable (() -> Unit)?, + prefix: String?, + suffix: String?, + supportingText: String?, + isError: Boolean, + singleLine: Boolean, + lines: Int +) = + androidx.compose.material3.OutlinedTextField( + value, + onValueChange, + modifier.platformModifier, + enabled, + readOnly, + label = label.ToNullableTextComposable(), + placeholder = placeholder.ToNullableTextComposable(), + leadingIcon = leadingIcon, + trailingIcon = trailingIcon, + prefix = prefix.ToNullableTextComposable(), + suffix = suffix.ToNullableTextComposable(), + supportingText = supportingText.ToNullableTextComposable(), + isError = isError, + singleLine = singleLine, + maxLines = lines, + minLines = lines + ) diff --git a/compose-multiplatform-material3/src/commonMain/kotlin/com/huanshankeji/compose/material3/ext/TextField.kt b/compose-multiplatform-material3/src/commonMain/kotlin/com/huanshankeji/compose/material3/ext/TextField.kt new file mode 100644 index 00000000..bdca9427 --- /dev/null +++ b/compose-multiplatform-material3/src/commonMain/kotlin/com/huanshankeji/compose/material3/ext/TextField.kt @@ -0,0 +1,49 @@ +package com.huanshankeji.compose.material3.ext + +import androidx.compose.runtime.Composable +import com.huanshankeji.compose.ui.Modifier + +// TODO `KeyboardOptions` which relates to `InputMode` and `InputType` on JS, and `KeyboardActions` + +@Composable +expect fun TextField( + value: String, + onValueChange: (String) -> Unit, + modifier: Modifier = Modifier, + enabled: Boolean = true, + readOnly: Boolean = false, + label: String? = null, + placeholder: String? = null, + leadingIcon: @Composable (() -> Unit)? = null, + trailingIcon: @Composable (() -> Unit)? = null, + prefix: String? = null, + suffix: String? = null, + supportingText: String? = null, + isError: Boolean = false, + singleLine: Boolean = false, + lines: Int = 1 + /* + maxLines: Int = if (singleLine) 1 else Int.MAX_VALUE, + minLines: Int = 1 + */ + // pattern: String? // This can be supported with Kotlin's `Regex` so it's not supported here. +) + +@Composable +expect fun OutlinedTextField( + value: String, + onValueChange: (String) -> Unit, + modifier: Modifier = Modifier, + enabled: Boolean = true, + readOnly: Boolean = false, + label: String? = null, + placeholder: String? = null, + leadingIcon: @Composable (() -> Unit)? = null, + trailingIcon: @Composable (() -> Unit)? = null, + prefix: String? = null, + suffix: String? = null, + supportingText: String? = null, + isError: Boolean = false, + singleLine: Boolean = false, + lines: Int = 1 +) diff --git a/compose-multiplatform-material3/src/jsMain/kotlin/com/huanshankeji/compose/material3/ext/TextField.js.kt b/compose-multiplatform-material3/src/jsMain/kotlin/com/huanshankeji/compose/material3/ext/TextField.js.kt new file mode 100644 index 00000000..67a6ef52 --- /dev/null +++ b/compose-multiplatform-material3/src/jsMain/kotlin/com/huanshankeji/compose/material3/ext/TextField.js.kt @@ -0,0 +1,107 @@ +package com.huanshankeji.compose.material3.ext + +import androidx.compose.runtime.Composable +import com.huanshankeji.compose.html.material3.MdFilledTextField +import com.huanshankeji.compose.html.material3.MdOutlinedTextField +import com.huanshankeji.compose.html.material3.MdTextFieldScope +import com.huanshankeji.compose.ui.Modifier +import com.huanshankeji.compose.web.attributes.isFalseOrNull +import com.huanshankeji.compose.web.attributes.isTrueOrNull +import com.huanshankeji.compose.web.attributes.onInput +import com.huanshankeji.compose.web.dom.value +import com.varabyte.kobweb.compose.ui.attrsModifier +import com.varabyte.kobweb.compose.ui.toAttrs +import org.jetbrains.compose.web.attributes.AttrsScope +import org.w3c.dom.HTMLElement +import com.varabyte.kobweb.compose.ui.Modifier as PlatformModifier + +private fun Modifier.toTextFieldAttrs( + onValueChange: (String) -> Unit +): AttrsScope.() -> Unit = + platformModifier.toAttrs { + onInput { onValueChange(it.target.value) } + } + +private fun TextFieldContent(): @Composable MdTextFieldScope.() -> Unit = { + // leadingIcon?.invoke() // TODO + PlatformModifier.attrsModifier { slot(MdTextFieldScope.Slot.LeadingIcon) } + // trailingIcon?.invoke() // TODO + PlatformModifier.attrsModifier { slot(MdTextFieldScope.Slot.TrailingIcon) } +} + +@Composable +actual fun TextField( + value: String, + onValueChange: (String) -> Unit, + modifier: Modifier, + enabled: Boolean, + readOnly: Boolean, + label: String?, + placeholder: String?, + leadingIcon: @Composable (() -> Unit)?, + trailingIcon: @Composable (() -> Unit)?, + prefix: String?, + suffix: String?, + supportingText: String?, + isError: Boolean, + singleLine: Boolean, + lines: Int +) = + MdFilledTextField( + enabled.isFalseOrNull(), + isError.isTrueOrNull(), + supportingText, // TODO Is passing `supportingText` as `errorText` correct? + label, + value = value, + prefixText = prefix, + suffixText = suffix, + hasLeadingIcon = leadingIcon?.let { true }, + hasTrailingIcon = trailingIcon?.let { true }, + supportingText = supportingText, + rows = if (singleLine) null else lines, + //inputMode = TODO(), + placeholder = placeholder, + readOnly = readOnly.isTrueOrNull(), + + attrs = modifier.toTextFieldAttrs(onValueChange), + content = TextFieldContent() + ) + + +@Composable +actual fun OutlinedTextField( + value: String, + onValueChange: (String) -> Unit, + modifier: Modifier, + enabled: Boolean, + readOnly: Boolean, + label: String?, + placeholder: String?, + leadingIcon: @Composable (() -> Unit)?, + trailingIcon: @Composable (() -> Unit)?, + prefix: String?, + suffix: String?, + supportingText: String?, + isError: Boolean, + singleLine: Boolean, + lines: Int +) = + MdOutlinedTextField( + enabled.isFalseOrNull(), + isError.isTrueOrNull(), + supportingText, // TODO Is passing `supportingText` as `errorText` correct? + label, + value = value, + prefixText = prefix, + suffixText = suffix, + hasLeadingIcon = leadingIcon?.let { true }, + hasTrailingIcon = trailingIcon?.let { true }, + supportingText = supportingText, + rows = if (singleLine) null else lines, + //inputMode = TODO(), + placeholder = placeholder, + readOnly = readOnly.isTrueOrNull(), + + attrs = modifier.toTextFieldAttrs(onValueChange), + content = TextFieldContent() + ) diff --git a/demo/src/commonMain/kotlin/com/huanshankeji/compose/material/demo/Material3.kt b/demo/src/commonMain/kotlin/com/huanshankeji/compose/material/demo/Material3.kt index ffe81391..e3b17843 100644 --- a/demo/src/commonMain/kotlin/com/huanshankeji/compose/material/demo/Material3.kt +++ b/demo/src/commonMain/kotlin/com/huanshankeji/compose/material/demo/Material3.kt @@ -34,5 +34,9 @@ fun Material3() { Checkbox(checked, { checked = it }) Switch(checked, { checked = it }) } + + var text by remember { mutableStateOf("") } + TextField(text, { text = it }) + OutlinedTextField(text, { text = it }) } } From 8f130c2d99b459d0a019fdd3b9a147f90b75556e Mon Sep 17 00:00:00 2001 From: Shreck Ye Date: Mon, 29 Apr 2024 03:40:51 +0800 Subject: [PATCH 43/75] Adapt to the latest changes in "com.huanshankeji:compose-html-common:0.3.0-SNAPSHOT" (https://github.com/huanshankeji/compose-html-material/commit/1923360f11f5a71ba15e8fcede461607ced18e97) --- .../kotlin/com/huanshankeji/compose/material3/Checkbox.js.kt | 2 +- .../kotlin/com/huanshankeji/compose/material3/Switch.js.kt | 2 +- .../com/huanshankeji/compose/material3/ext/TextField.js.kt | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/compose-multiplatform-material3/src/jsMain/kotlin/com/huanshankeji/compose/material3/Checkbox.js.kt b/compose-multiplatform-material3/src/jsMain/kotlin/com/huanshankeji/compose/material3/Checkbox.js.kt index e1b3e232..f42709e3 100644 --- a/compose-multiplatform-material3/src/jsMain/kotlin/com/huanshankeji/compose/material3/Checkbox.js.kt +++ b/compose-multiplatform-material3/src/jsMain/kotlin/com/huanshankeji/compose/material3/Checkbox.js.kt @@ -3,9 +3,9 @@ package com.huanshankeji.compose.material3 import androidx.compose.runtime.Composable import com.huanshankeji.compose.html.material3.MdCheckbox import com.huanshankeji.compose.ui.Modifier +import com.huanshankeji.compose.web.attributes.ext.onInput import com.huanshankeji.compose.web.attributes.isFalseOrNull import com.huanshankeji.compose.web.attributes.isTrueOrNull -import com.huanshankeji.compose.web.attributes.onInput import com.varabyte.kobweb.compose.ui.toAttrs @Composable diff --git a/compose-multiplatform-material3/src/jsMain/kotlin/com/huanshankeji/compose/material3/Switch.js.kt b/compose-multiplatform-material3/src/jsMain/kotlin/com/huanshankeji/compose/material3/Switch.js.kt index a0481230..325cf8fb 100644 --- a/compose-multiplatform-material3/src/jsMain/kotlin/com/huanshankeji/compose/material3/Switch.js.kt +++ b/compose-multiplatform-material3/src/jsMain/kotlin/com/huanshankeji/compose/material3/Switch.js.kt @@ -3,9 +3,9 @@ package com.huanshankeji.compose.material3 import androidx.compose.runtime.Composable import com.huanshankeji.compose.html.material3.MdSwitch import com.huanshankeji.compose.ui.Modifier +import com.huanshankeji.compose.web.attributes.ext.onInput import com.huanshankeji.compose.web.attributes.isFalseOrNull import com.huanshankeji.compose.web.attributes.isTrueOrNull -import com.huanshankeji.compose.web.attributes.onInput import com.varabyte.kobweb.compose.ui.toAttrs @Composable diff --git a/compose-multiplatform-material3/src/jsMain/kotlin/com/huanshankeji/compose/material3/ext/TextField.js.kt b/compose-multiplatform-material3/src/jsMain/kotlin/com/huanshankeji/compose/material3/ext/TextField.js.kt index 67a6ef52..fc430a5d 100644 --- a/compose-multiplatform-material3/src/jsMain/kotlin/com/huanshankeji/compose/material3/ext/TextField.js.kt +++ b/compose-multiplatform-material3/src/jsMain/kotlin/com/huanshankeji/compose/material3/ext/TextField.js.kt @@ -5,10 +5,10 @@ import com.huanshankeji.compose.html.material3.MdFilledTextField import com.huanshankeji.compose.html.material3.MdOutlinedTextField import com.huanshankeji.compose.html.material3.MdTextFieldScope import com.huanshankeji.compose.ui.Modifier +import com.huanshankeji.compose.web.attributes.ext.onInput import com.huanshankeji.compose.web.attributes.isFalseOrNull import com.huanshankeji.compose.web.attributes.isTrueOrNull -import com.huanshankeji.compose.web.attributes.onInput -import com.huanshankeji.compose.web.dom.value +import com.huanshankeji.compose.web.dom.ext.value import com.varabyte.kobweb.compose.ui.attrsModifier import com.varabyte.kobweb.compose.ui.toAttrs import org.jetbrains.compose.web.attributes.AttrsScope From df80e7e11d1cdbc88736e33e329ccae6dabd8ab7 Mon Sep 17 00:00:00 2001 From: Shreck Ye Date: Mon, 29 Apr 2024 18:38:37 +0800 Subject: [PATCH 44/75] Copy and adapt `KeyboardOptions` and `KeyboardActions` from `androidx.compose.foundation.text` --- .../PlatformImeOptions.androidxCommon.kt | 3 ++ .../foundation/text/KeyboardActions.kt | 15 ++++++ .../foundation/text/KeyboardOptions.kt | 25 +++++++++ .../foundation/text/input/ImeAction.kt | 48 +++++++++++++++++ .../text/input/KeyboardCapitalization.kt | 31 +++++++++++ .../foundation/text/input/KeyboardType.kt | 52 +++++++++++++++++++ .../text/input/PlatformImeOptions.kt | 3 ++ .../text/input/PlatformImeOptions.js.kt | 3 ++ 8 files changed, 180 insertions(+) create mode 100644 compose-multiplatform-common/src/androidxCommonMain/kotlin/com/huanshankeji/compose/foundation/text/input/PlatformImeOptions.androidxCommon.kt create mode 100644 compose-multiplatform-common/src/commonMain/kotlin/com/huanshankeji/compose/foundation/text/KeyboardActions.kt create mode 100644 compose-multiplatform-common/src/commonMain/kotlin/com/huanshankeji/compose/foundation/text/KeyboardOptions.kt create mode 100644 compose-multiplatform-common/src/commonMain/kotlin/com/huanshankeji/compose/foundation/text/input/ImeAction.kt create mode 100644 compose-multiplatform-common/src/commonMain/kotlin/com/huanshankeji/compose/foundation/text/input/KeyboardCapitalization.kt create mode 100644 compose-multiplatform-common/src/commonMain/kotlin/com/huanshankeji/compose/foundation/text/input/KeyboardType.kt create mode 100644 compose-multiplatform-common/src/commonMain/kotlin/com/huanshankeji/compose/foundation/text/input/PlatformImeOptions.kt create mode 100644 compose-multiplatform-common/src/jsMain/kotlin/com/huanshankeji/compose/foundation/text/input/PlatformImeOptions.js.kt diff --git a/compose-multiplatform-common/src/androidxCommonMain/kotlin/com/huanshankeji/compose/foundation/text/input/PlatformImeOptions.androidxCommon.kt b/compose-multiplatform-common/src/androidxCommonMain/kotlin/com/huanshankeji/compose/foundation/text/input/PlatformImeOptions.androidxCommon.kt new file mode 100644 index 00000000..49429ee3 --- /dev/null +++ b/compose-multiplatform-common/src/androidxCommonMain/kotlin/com/huanshankeji/compose/foundation/text/input/PlatformImeOptions.androidxCommon.kt @@ -0,0 +1,3 @@ +package com.huanshankeji.compose.foundation.text.input + +actual class PlatformImeOptions(val platformValue: androidx.compose.ui.text.input.PlatformImeOptions) \ No newline at end of file diff --git a/compose-multiplatform-common/src/commonMain/kotlin/com/huanshankeji/compose/foundation/text/KeyboardActions.kt b/compose-multiplatform-common/src/commonMain/kotlin/com/huanshankeji/compose/foundation/text/KeyboardActions.kt new file mode 100644 index 00000000..69ae823e --- /dev/null +++ b/compose-multiplatform-common/src/commonMain/kotlin/com/huanshankeji/compose/foundation/text/KeyboardActions.kt @@ -0,0 +1,15 @@ +package com.huanshankeji.compose.foundation.text + +import com.huanshankeji.compose.foundation.text.input.ImeAction +import kotlin.jvm.JvmInline + +// copied and adapted from `androidx.compose.foundation.text` + +@JvmInline +value class KeyboardActions( + val onAny: KeyboardActionScope.() -> Unit, +) + +interface KeyboardActionScope { + fun defaultKeyboardAction(imeAction: ImeAction) +} diff --git a/compose-multiplatform-common/src/commonMain/kotlin/com/huanshankeji/compose/foundation/text/KeyboardOptions.kt b/compose-multiplatform-common/src/commonMain/kotlin/com/huanshankeji/compose/foundation/text/KeyboardOptions.kt new file mode 100644 index 00000000..85e8595b --- /dev/null +++ b/compose-multiplatform-common/src/commonMain/kotlin/com/huanshankeji/compose/foundation/text/KeyboardOptions.kt @@ -0,0 +1,25 @@ +package com.huanshankeji.compose.foundation.text + +import androidx.compose.runtime.Immutable +import androidx.compose.runtime.Stable +import com.huanshankeji.compose.foundation.text.input.ImeAction +import com.huanshankeji.compose.foundation.text.input.KeyboardCapitalization +import com.huanshankeji.compose.foundation.text.input.KeyboardType +import com.huanshankeji.compose.foundation.text.input.PlatformImeOptions + +// copied and adapted from `androidx.compose.foundation.text.KeyboardOptions` +@Immutable +class KeyboardOptions( + val capitalization: KeyboardCapitalization = KeyboardCapitalization.None, + val autoCorrect: Boolean = true, + val keyboardType: KeyboardType = KeyboardType.Text, + val imeAction: ImeAction = ImeAction.Default, + val platformImeOptions: PlatformImeOptions? = null +) { + companion object { + @Stable + val Default = KeyboardOptions() + } + + // `copy`, `equals`, `hashCode`, and `toString`, are removed. I am hoping to generated them with a plugin to reduce duplicate code. +} diff --git a/compose-multiplatform-common/src/commonMain/kotlin/com/huanshankeji/compose/foundation/text/input/ImeAction.kt b/compose-multiplatform-common/src/commonMain/kotlin/com/huanshankeji/compose/foundation/text/input/ImeAction.kt new file mode 100644 index 00000000..88b31c2d --- /dev/null +++ b/compose-multiplatform-common/src/commonMain/kotlin/com/huanshankeji/compose/foundation/text/input/ImeAction.kt @@ -0,0 +1,48 @@ +package com.huanshankeji.compose.foundation.text.input + +import androidx.compose.runtime.Stable + +// copied and adapted from `androidx.compose.foundation.text.input.ImeAction` +@kotlin.jvm.JvmInline +value class ImeAction internal constructor(@Suppress("unused") private val value: Int) { + + override fun toString(): String { + return when (this) { + None -> "None" + Default -> "Default" + Go -> "Go" + Search -> "Search" + Send -> "Send" + Previous -> "Previous" + Next -> "Next" + Done -> "Done" + else -> "Invalid" + } + } + + companion object { + @Stable + val Default: ImeAction = ImeAction(1) + + @Stable + val None: ImeAction = ImeAction(0) + + @Stable + val Go: ImeAction = ImeAction(2) + + @Stable + val Search: ImeAction = ImeAction(3) + + @Stable + val Send: ImeAction = ImeAction(4) + + @Stable + val Previous: ImeAction = ImeAction(5) + + @Stable + val Next: ImeAction = ImeAction(6) + + @Stable + val Done: ImeAction = ImeAction(7) + } +} diff --git a/compose-multiplatform-common/src/commonMain/kotlin/com/huanshankeji/compose/foundation/text/input/KeyboardCapitalization.kt b/compose-multiplatform-common/src/commonMain/kotlin/com/huanshankeji/compose/foundation/text/input/KeyboardCapitalization.kt new file mode 100644 index 00000000..913b602e --- /dev/null +++ b/compose-multiplatform-common/src/commonMain/kotlin/com/huanshankeji/compose/foundation/text/input/KeyboardCapitalization.kt @@ -0,0 +1,31 @@ +package com.huanshankeji.compose.foundation.text.input + +import androidx.compose.runtime.Stable + +// copied and adapted from `androidx.compose.foundation.text.input.KeyboardCapitalization` +@kotlin.jvm.JvmInline +value class KeyboardCapitalization internal constructor(internal val value: Int) { + override fun toString(): String { + return when (this) { + None -> "None" + Characters -> "Characters" + Words -> "Words" + Sentences -> "Sentences" + else -> "Invalid" + } + } + + companion object { + @Stable + val None = KeyboardCapitalization(0) + + @Stable + val Characters = KeyboardCapitalization(1) + + @Stable + val Words = KeyboardCapitalization(2) + + @Stable + val Sentences = KeyboardCapitalization(3) + } +} diff --git a/compose-multiplatform-common/src/commonMain/kotlin/com/huanshankeji/compose/foundation/text/input/KeyboardType.kt b/compose-multiplatform-common/src/commonMain/kotlin/com/huanshankeji/compose/foundation/text/input/KeyboardType.kt new file mode 100644 index 00000000..14f5210d --- /dev/null +++ b/compose-multiplatform-common/src/commonMain/kotlin/com/huanshankeji/compose/foundation/text/input/KeyboardType.kt @@ -0,0 +1,52 @@ +package com.huanshankeji.compose.foundation.text.input + +import androidx.compose.runtime.Stable + +// copied and adapted from `androidx.compose.foundation.text.input.KeyboardType` +@kotlin.jvm.JvmInline +value class KeyboardType internal constructor(@Suppress("unused") private val value: Int) { + + override fun toString(): String { + return when (this) { + Text -> "Text" + Ascii -> "Ascii" + Number -> "Number" + Phone -> "Phone" + Uri -> "Uri" + Email -> "Email" + Password -> "Password" + NumberPassword -> "NumberPassword" + Decimal -> "Decimal" + else -> "Invalid" + } + } + + companion object { + @Stable + val Text: KeyboardType = KeyboardType(1) + + @Stable + val Ascii: KeyboardType = KeyboardType(2) + + @Stable + val Number: KeyboardType = KeyboardType(3) + + @Stable + val Phone: KeyboardType = KeyboardType(4) + + @Stable + val Uri: KeyboardType = KeyboardType(5) + + @Stable + val Email: KeyboardType = KeyboardType(6) + + @Stable + val Password: KeyboardType = KeyboardType(7) + + @Stable + val NumberPassword: KeyboardType = KeyboardType(8) + + @Stable + val Decimal: KeyboardType = KeyboardType(9) + } +} diff --git a/compose-multiplatform-common/src/commonMain/kotlin/com/huanshankeji/compose/foundation/text/input/PlatformImeOptions.kt b/compose-multiplatform-common/src/commonMain/kotlin/com/huanshankeji/compose/foundation/text/input/PlatformImeOptions.kt new file mode 100644 index 00000000..960c21c3 --- /dev/null +++ b/compose-multiplatform-common/src/commonMain/kotlin/com/huanshankeji/compose/foundation/text/input/PlatformImeOptions.kt @@ -0,0 +1,3 @@ +package com.huanshankeji.compose.foundation.text.input + +expect class PlatformImeOptions \ No newline at end of file diff --git a/compose-multiplatform-common/src/jsMain/kotlin/com/huanshankeji/compose/foundation/text/input/PlatformImeOptions.js.kt b/compose-multiplatform-common/src/jsMain/kotlin/com/huanshankeji/compose/foundation/text/input/PlatformImeOptions.js.kt new file mode 100644 index 00000000..dea83f39 --- /dev/null +++ b/compose-multiplatform-common/src/jsMain/kotlin/com/huanshankeji/compose/foundation/text/input/PlatformImeOptions.js.kt @@ -0,0 +1,3 @@ +package com.huanshankeji.compose.foundation.text.input + +actual class PlatformImeOptions \ No newline at end of file From 67c2c127100c7953222d6753b9ea15cf6baf8274 Mon Sep 17 00:00:00 2001 From: Shreck Ye Date: Tue, 30 Apr 2024 02:45:25 +0800 Subject: [PATCH 45/75] Support `KeyboardOptions` and `KeyboardActions` in the text field composables on both platforms The corresponding commit: https://github.com/huanshankeji/compose-html-material/commit/8278613922a17a5b6a6199121b768604710e3785 --- compose-multiplatform-common/build.gradle.kts | 1 + .../text/KeyboardActions.androidxCommon.kt | 19 +++++++++ .../text/KeyboardOptions.androidxCommon.kt | 13 +++++++ .../text/input/ImeAction.androidxCommon.kt | 20 ++++++++++ .../KeyboardCapitalization.androidxCommon.kt | 16 ++++++++ .../text/input/KeyboardType.androidxCommon.kt | 21 ++++++++++ .../foundation/text/KeyboardActions.kt | 16 +++++++- .../foundation/text/KeyboardOptions.kt | 8 ++-- .../foundation/text/input/KeyboardType.kt | 3 ++ .../foundation/text/KeyboardOptions.js.kt | 27 +++++++++++++ .../KeyboardOptionsAndKeyboardActions.js.kt | 14 +++++++ .../text/input/KeyboardCapitalization.js.kt | 5 +++ .../foundation/text/input/KeyboardType.js.kt | 19 +++++++++ .../material/ext/TextField.androidxCommon.kt | 15 +++++++ .../compose/material/ext/TextField.kt | 8 ++++ .../compose/material/ext/TextField.js.kt | 39 +++++++++++++++++-- .../material3/ext/TextField.androidxCommon.kt | 11 ++++++ .../compose/material3/ext/TextField.kt | 8 +++- .../compose/material3/ext/TextField.js.kt | 18 ++++++--- .../compose/material/demo/Material2.kt | 3 ++ .../compose/material/demo/Material3.kt | 4 +- 21 files changed, 271 insertions(+), 17 deletions(-) create mode 100644 compose-multiplatform-common/src/androidxCommonMain/kotlin/com/huanshankeji/compose/foundation/text/KeyboardActions.androidxCommon.kt create mode 100644 compose-multiplatform-common/src/androidxCommonMain/kotlin/com/huanshankeji/compose/foundation/text/KeyboardOptions.androidxCommon.kt create mode 100644 compose-multiplatform-common/src/androidxCommonMain/kotlin/com/huanshankeji/compose/foundation/text/input/ImeAction.androidxCommon.kt create mode 100644 compose-multiplatform-common/src/androidxCommonMain/kotlin/com/huanshankeji/compose/foundation/text/input/KeyboardCapitalization.androidxCommon.kt create mode 100644 compose-multiplatform-common/src/androidxCommonMain/kotlin/com/huanshankeji/compose/foundation/text/input/KeyboardType.androidxCommon.kt create mode 100644 compose-multiplatform-common/src/jsMain/kotlin/com/huanshankeji/compose/foundation/text/KeyboardOptions.js.kt create mode 100644 compose-multiplatform-common/src/jsMain/kotlin/com/huanshankeji/compose/foundation/text/KeyboardOptionsAndKeyboardActions.js.kt create mode 100644 compose-multiplatform-common/src/jsMain/kotlin/com/huanshankeji/compose/foundation/text/input/KeyboardCapitalization.js.kt create mode 100644 compose-multiplatform-common/src/jsMain/kotlin/com/huanshankeji/compose/foundation/text/input/KeyboardType.js.kt diff --git a/compose-multiplatform-common/build.gradle.kts b/compose-multiplatform-common/build.gradle.kts index 885eb0c2..1c94940d 100644 --- a/compose-multiplatform-common/build.gradle.kts +++ b/compose-multiplatform-common/build.gradle.kts @@ -38,6 +38,7 @@ kotlin { api(compose.html.core) // see: https://github.com/varabyte/kobweb/blob/main/frontend/kobweb-compose/build.gradle.kts api("com.varabyte.kobweb:kobweb-compose:${DependencyVersions.kobweb}") + implementation("com.huanshankeji:compose-html-common:${DependencyVersions.huanshankejiComposeHtml}") } } } diff --git a/compose-multiplatform-common/src/androidxCommonMain/kotlin/com/huanshankeji/compose/foundation/text/KeyboardActions.androidxCommon.kt b/compose-multiplatform-common/src/androidxCommonMain/kotlin/com/huanshankeji/compose/foundation/text/KeyboardActions.androidxCommon.kt new file mode 100644 index 00000000..51ebf8e4 --- /dev/null +++ b/compose-multiplatform-common/src/androidxCommonMain/kotlin/com/huanshankeji/compose/foundation/text/KeyboardActions.androidxCommon.kt @@ -0,0 +1,19 @@ +package com.huanshankeji.compose.foundation.text + +import com.huanshankeji.compose.foundation.text.input.ImeAction +import com.huanshankeji.compose.foundation.text.input.toPlatformValue +import androidx.compose.foundation.text.KeyboardActionScope as PlatformKeyboardActionScope +import androidx.compose.foundation.text.KeyboardActions as PlatformKeyboardActions + +fun KeyboardActions.toPlatformValue(): PlatformKeyboardActions = + onAny?.let { + PlatformKeyboardActions { + toCommonValue().it() + } + } ?: PlatformKeyboardActions() + +fun PlatformKeyboardActionScope.toCommonValue(): KeyboardActionScope = + object : KeyboardActionScope { + override fun defaultKeyboardAction(imeAction: ImeAction) = + this@toCommonValue.defaultKeyboardAction(imeAction.toPlatformValue()) + } diff --git a/compose-multiplatform-common/src/androidxCommonMain/kotlin/com/huanshankeji/compose/foundation/text/KeyboardOptions.androidxCommon.kt b/compose-multiplatform-common/src/androidxCommonMain/kotlin/com/huanshankeji/compose/foundation/text/KeyboardOptions.androidxCommon.kt new file mode 100644 index 00000000..0685efbd --- /dev/null +++ b/compose-multiplatform-common/src/androidxCommonMain/kotlin/com/huanshankeji/compose/foundation/text/KeyboardOptions.androidxCommon.kt @@ -0,0 +1,13 @@ +package com.huanshankeji.compose.foundation.text + +import com.huanshankeji.compose.foundation.text.input.toPlatformValue +import androidx.compose.foundation.text.KeyboardOptions as PlatformKeyboardOptions + +fun KeyboardOptions.toPlatformValue(): PlatformKeyboardOptions = + PlatformKeyboardOptions( + capitalization.toPlatformValue(), + autoCorrect ?: true, + keyboardType.toPlatformValue(), + imeAction.toPlatformValue(), + platformImeOptions?.platformValue + ) diff --git a/compose-multiplatform-common/src/androidxCommonMain/kotlin/com/huanshankeji/compose/foundation/text/input/ImeAction.androidxCommon.kt b/compose-multiplatform-common/src/androidxCommonMain/kotlin/com/huanshankeji/compose/foundation/text/input/ImeAction.androidxCommon.kt new file mode 100644 index 00000000..1299ff15 --- /dev/null +++ b/compose-multiplatform-common/src/androidxCommonMain/kotlin/com/huanshankeji/compose/foundation/text/input/ImeAction.androidxCommon.kt @@ -0,0 +1,20 @@ +package com.huanshankeji.compose.foundation.text.input + +import androidx.compose.ui.text.input.ImeAction as PlatformImeAction + +fun ImeAction.toPlatformValue(): PlatformImeAction = + when (this) { + ImeAction.Default -> PlatformImeAction.Default + ImeAction.None -> PlatformImeAction.None + ImeAction.Go -> PlatformImeAction.Go + ImeAction.Search -> PlatformImeAction.Search + ImeAction.Send -> PlatformImeAction.Search + ImeAction.Previous -> PlatformImeAction.Previous + ImeAction.Next -> PlatformImeAction.Next + ImeAction.Done -> PlatformImeAction.Done + + else -> throw IllegalArgumentException(toString()) + } + +fun ImeAction?.toPlatformValue(): PlatformImeAction = + this?.toPlatformValue() ?: PlatformImeAction.Default diff --git a/compose-multiplatform-common/src/androidxCommonMain/kotlin/com/huanshankeji/compose/foundation/text/input/KeyboardCapitalization.androidxCommon.kt b/compose-multiplatform-common/src/androidxCommonMain/kotlin/com/huanshankeji/compose/foundation/text/input/KeyboardCapitalization.androidxCommon.kt new file mode 100644 index 00000000..f448c868 --- /dev/null +++ b/compose-multiplatform-common/src/androidxCommonMain/kotlin/com/huanshankeji/compose/foundation/text/input/KeyboardCapitalization.androidxCommon.kt @@ -0,0 +1,16 @@ +package com.huanshankeji.compose.foundation.text.input + +import androidx.compose.ui.text.input.KeyboardCapitalization as PlatformKeyboardCapitalization + +fun KeyboardCapitalization.toPlatformValue(): PlatformKeyboardCapitalization = + when (this) { + KeyboardCapitalization.None -> PlatformKeyboardCapitalization.None + KeyboardCapitalization.Characters -> PlatformKeyboardCapitalization.Characters + KeyboardCapitalization.Words -> PlatformKeyboardCapitalization.Words + KeyboardCapitalization.Sentences -> PlatformKeyboardCapitalization.Sentences + + else -> throw IllegalArgumentException(toString()) + } + +fun KeyboardCapitalization?.toPlatformValue(): PlatformKeyboardCapitalization = + this?.toPlatformValue() ?: PlatformKeyboardCapitalization.None diff --git a/compose-multiplatform-common/src/androidxCommonMain/kotlin/com/huanshankeji/compose/foundation/text/input/KeyboardType.androidxCommon.kt b/compose-multiplatform-common/src/androidxCommonMain/kotlin/com/huanshankeji/compose/foundation/text/input/KeyboardType.androidxCommon.kt new file mode 100644 index 00000000..4850f3ad --- /dev/null +++ b/compose-multiplatform-common/src/androidxCommonMain/kotlin/com/huanshankeji/compose/foundation/text/input/KeyboardType.androidxCommon.kt @@ -0,0 +1,21 @@ +package com.huanshankeji.compose.foundation.text.input + +import androidx.compose.ui.text.input.KeyboardType as PlatformKeyboardType + +fun KeyboardType.toPlatformValue(): PlatformKeyboardType = + when (this) { + KeyboardType.Text -> PlatformKeyboardType.Text + KeyboardType.Ascii -> PlatformKeyboardType.Ascii + KeyboardType.Number -> PlatformKeyboardType.Number + KeyboardType.Phone -> PlatformKeyboardType.Phone + KeyboardType.Uri -> PlatformKeyboardType.Uri + KeyboardType.Email -> PlatformKeyboardType.Email + KeyboardType.Password -> PlatformKeyboardType.Password + KeyboardType.NumberPassword -> PlatformKeyboardType.NumberPassword + KeyboardType.Decimal -> PlatformKeyboardType.Decimal + + else -> throw IllegalArgumentException(toString()) + } + +fun KeyboardType?.toPlatformValue(): PlatformKeyboardType = + this?.toPlatformValue() ?: PlatformKeyboardType.Text diff --git a/compose-multiplatform-common/src/commonMain/kotlin/com/huanshankeji/compose/foundation/text/KeyboardActions.kt b/compose-multiplatform-common/src/commonMain/kotlin/com/huanshankeji/compose/foundation/text/KeyboardActions.kt index 69ae823e..d7703ea5 100644 --- a/compose-multiplatform-common/src/commonMain/kotlin/com/huanshankeji/compose/foundation/text/KeyboardActions.kt +++ b/compose-multiplatform-common/src/commonMain/kotlin/com/huanshankeji/compose/foundation/text/KeyboardActions.kt @@ -1,5 +1,6 @@ package com.huanshankeji.compose.foundation.text +import androidx.compose.runtime.Stable import com.huanshankeji.compose.foundation.text.input.ImeAction import kotlin.jvm.JvmInline @@ -7,9 +8,20 @@ import kotlin.jvm.JvmInline @JvmInline value class KeyboardActions( - val onAny: KeyboardActionScope.() -> Unit, -) + val onAny: (KeyboardActionScope.() -> Unit)? = null, +) { + companion object { + @Stable + val Default: KeyboardActions = KeyboardActions() + } +} interface KeyboardActionScope { fun defaultKeyboardAction(imeAction: ImeAction) + + object DoNothingInstance : KeyboardActionScope { + override fun defaultKeyboardAction(imeAction: ImeAction) { + // do nothing for now + } + } } diff --git a/compose-multiplatform-common/src/commonMain/kotlin/com/huanshankeji/compose/foundation/text/KeyboardOptions.kt b/compose-multiplatform-common/src/commonMain/kotlin/com/huanshankeji/compose/foundation/text/KeyboardOptions.kt index 85e8595b..7fa37f46 100644 --- a/compose-multiplatform-common/src/commonMain/kotlin/com/huanshankeji/compose/foundation/text/KeyboardOptions.kt +++ b/compose-multiplatform-common/src/commonMain/kotlin/com/huanshankeji/compose/foundation/text/KeyboardOptions.kt @@ -10,10 +10,10 @@ import com.huanshankeji.compose.foundation.text.input.PlatformImeOptions // copied and adapted from `androidx.compose.foundation.text.KeyboardOptions` @Immutable class KeyboardOptions( - val capitalization: KeyboardCapitalization = KeyboardCapitalization.None, - val autoCorrect: Boolean = true, - val keyboardType: KeyboardType = KeyboardType.Text, - val imeAction: ImeAction = ImeAction.Default, + val capitalization: KeyboardCapitalization? = null, + val autoCorrect: Boolean? = null, + val keyboardType: KeyboardType? = null, + val imeAction: ImeAction? = null, val platformImeOptions: PlatformImeOptions? = null ) { companion object { diff --git a/compose-multiplatform-common/src/commonMain/kotlin/com/huanshankeji/compose/foundation/text/input/KeyboardType.kt b/compose-multiplatform-common/src/commonMain/kotlin/com/huanshankeji/compose/foundation/text/input/KeyboardType.kt index 14f5210d..cf20c278 100644 --- a/compose-multiplatform-common/src/commonMain/kotlin/com/huanshankeji/compose/foundation/text/input/KeyboardType.kt +++ b/compose-multiplatform-common/src/commonMain/kotlin/com/huanshankeji/compose/foundation/text/input/KeyboardType.kt @@ -25,6 +25,7 @@ value class KeyboardType internal constructor(@Suppress("unused") private val va @Stable val Text: KeyboardType = KeyboardType(1) + // doesn't work on JS yet @Stable val Ascii: KeyboardType = KeyboardType(2) @@ -40,9 +41,11 @@ value class KeyboardType internal constructor(@Suppress("unused") private val va @Stable val Email: KeyboardType = KeyboardType(6) + // doesn't work on JS yet @Stable val Password: KeyboardType = KeyboardType(7) + // doesn't work on JS yet @Stable val NumberPassword: KeyboardType = KeyboardType(8) diff --git a/compose-multiplatform-common/src/jsMain/kotlin/com/huanshankeji/compose/foundation/text/KeyboardOptions.js.kt b/compose-multiplatform-common/src/jsMain/kotlin/com/huanshankeji/compose/foundation/text/KeyboardOptions.js.kt new file mode 100644 index 00000000..517ded83 --- /dev/null +++ b/compose-multiplatform-common/src/jsMain/kotlin/com/huanshankeji/compose/foundation/text/KeyboardOptions.js.kt @@ -0,0 +1,27 @@ +package com.huanshankeji.compose.foundation.text + +import com.huanshankeji.compose.foundation.text.input.toAutoCapitalizeAttrValue +import com.huanshankeji.compose.foundation.text.input.toInputMode +import com.huanshankeji.compose.web.attributes.autocorrect +import com.huanshankeji.compose.web.attributes.ext.autoCapitalizeRequiringValid +import com.huanshankeji.compose.web.attributes.ext.enterKeyHintIfValid +import org.jetbrains.compose.web.attributes.AttrsScope + +fun AttrsScope<*>.attrsFrom(keyboardOptions: KeyboardOptions) { + with(keyboardOptions) { + capitalization?.let { autoCapitalizeRequiringValid(it.toAutoCapitalizeAttrValue()) } + autoCorrect?.let { + // https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/spellcheck + spellCheck(it) + autocorrect(it) + } + // https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/inputmode + keyboardType?.toInputMode()?.let { inputMode(it) } + imeAction?.let { + // Also see: https://stackoverflow.com/questions/24278088/showing-search-button-as-submit-button-in-mobile-devices-keyboards + @Suppress("DEPRECATION") + enterKeyHintIfValid(it.toString().decapitalize()) + } + //platformImeOptions + } +} diff --git a/compose-multiplatform-common/src/jsMain/kotlin/com/huanshankeji/compose/foundation/text/KeyboardOptionsAndKeyboardActions.js.kt b/compose-multiplatform-common/src/jsMain/kotlin/com/huanshankeji/compose/foundation/text/KeyboardOptionsAndKeyboardActions.js.kt new file mode 100644 index 00000000..cbddafa1 --- /dev/null +++ b/compose-multiplatform-common/src/jsMain/kotlin/com/huanshankeji/compose/foundation/text/KeyboardOptionsAndKeyboardActions.js.kt @@ -0,0 +1,14 @@ +package com.huanshankeji.compose.foundation.text + +import org.jetbrains.compose.web.attributes.AttrsScope +import org.w3c.dom.HTMLElement + +fun AttrsScope.attrsFrom(keyboardOptions: KeyboardOptions, keyboardActions: KeyboardActions) { + attrsFrom(keyboardOptions) + keyboardActions.onAny?.let { + onKeyDown { + if (it.key == "Enter") + KeyboardActionScope.DoNothingInstance.it() + } + } +} diff --git a/compose-multiplatform-common/src/jsMain/kotlin/com/huanshankeji/compose/foundation/text/input/KeyboardCapitalization.js.kt b/compose-multiplatform-common/src/jsMain/kotlin/com/huanshankeji/compose/foundation/text/input/KeyboardCapitalization.js.kt new file mode 100644 index 00000000..c6e93303 --- /dev/null +++ b/compose-multiplatform-common/src/jsMain/kotlin/com/huanshankeji/compose/foundation/text/input/KeyboardCapitalization.js.kt @@ -0,0 +1,5 @@ +package com.huanshankeji.compose.foundation.text.input + +fun KeyboardCapitalization.toAutoCapitalizeAttrValue() = + @Suppress("DEPRECATION") + toString().decapitalize() diff --git a/compose-multiplatform-common/src/jsMain/kotlin/com/huanshankeji/compose/foundation/text/input/KeyboardType.js.kt b/compose-multiplatform-common/src/jsMain/kotlin/com/huanshankeji/compose/foundation/text/input/KeyboardType.js.kt new file mode 100644 index 00000000..6d0d436c --- /dev/null +++ b/compose-multiplatform-common/src/jsMain/kotlin/com/huanshankeji/compose/foundation/text/input/KeyboardType.js.kt @@ -0,0 +1,19 @@ +package com.huanshankeji.compose.foundation.text.input + +import org.jetbrains.compose.web.attributes.InputMode + +fun KeyboardType.toInputMode(): InputMode? = + when (this) { + KeyboardType.Text -> InputMode.Text + KeyboardType.Ascii -> null + KeyboardType.Number -> InputMode.Numeric + KeyboardType.Phone -> InputMode.Tel + KeyboardType.Uri -> InputMode.Url + KeyboardType.Email -> InputMode.Email + // TODO + KeyboardType.Password -> null + KeyboardType.NumberPassword -> null + KeyboardType.Decimal -> InputMode.Decimal + + else -> throw IllegalArgumentException(toString()) + } diff --git a/compose-multiplatform-material/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material/ext/TextField.androidxCommon.kt b/compose-multiplatform-material/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material/ext/TextField.androidxCommon.kt index 2ac90b20..5fe95ec7 100644 --- a/compose-multiplatform-material/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material/ext/TextField.androidxCommon.kt +++ b/compose-multiplatform-material/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material/ext/TextField.androidxCommon.kt @@ -1,6 +1,9 @@ package com.huanshankeji.compose.material.ext import androidx.compose.runtime.Composable +import com.huanshankeji.compose.foundation.text.KeyboardActions +import com.huanshankeji.compose.foundation.text.KeyboardOptions +import com.huanshankeji.compose.foundation.text.toPlatformValue import com.huanshankeji.compose.material.Text import com.huanshankeji.compose.ui.Modifier @@ -13,6 +16,8 @@ actual fun TextField( label: String?, leadingIcon: @Composable (() -> Unit)?, trailingIcon: @Composable (() -> Unit)?, + keyboardOptions: KeyboardOptions, + keyboardActions: KeyboardActions, singleLine: Boolean ) = androidx.compose.material.TextField( @@ -23,6 +28,8 @@ actual fun TextField( label = label?.let { { Text(it) } }, leadingIcon = leadingIcon, trailingIcon = trailingIcon, + keyboardOptions = keyboardOptions.toPlatformValue(), + keyboardActions = keyboardActions.toPlatformValue(), singleLine = singleLine ) @@ -35,6 +42,8 @@ actual fun OutlinedTextField( label: String?, leadingIcon: @Composable (() -> Unit)?, trailingIcon: @Composable (() -> Unit)?, + keyboardOptions: KeyboardOptions, + keyboardActions: KeyboardActions, singleLine: Boolean ) = androidx.compose.material.OutlinedTextField( @@ -45,6 +54,8 @@ actual fun OutlinedTextField( label = label?.let { { Text(it) } }, leadingIcon = leadingIcon, trailingIcon = trailingIcon, + keyboardOptions = keyboardOptions.toPlatformValue(), + keyboardActions = keyboardActions.toPlatformValue(), singleLine = singleLine ) @@ -55,6 +66,8 @@ actual fun TextArea( modifier: Modifier, enabled: Boolean, label: String?, + keyboardOptions: KeyboardOptions, + keyboardActions: KeyboardActions, lines: Int ) = androidx.compose.material.TextField( @@ -63,6 +76,8 @@ actual fun TextArea( modifier.platformModifier, enabled = enabled, label = label?.let { { Text(it) } }, + keyboardOptions = keyboardOptions.toPlatformValue(), + keyboardActions = keyboardActions.toPlatformValue(), maxLines = lines, minLines = lines ) diff --git a/compose-multiplatform-material/src/commonMain/kotlin/com/huanshankeji/compose/material/ext/TextField.kt b/compose-multiplatform-material/src/commonMain/kotlin/com/huanshankeji/compose/material/ext/TextField.kt index 1f7d69a7..b5519b4f 100644 --- a/compose-multiplatform-material/src/commonMain/kotlin/com/huanshankeji/compose/material/ext/TextField.kt +++ b/compose-multiplatform-material/src/commonMain/kotlin/com/huanshankeji/compose/material/ext/TextField.kt @@ -1,6 +1,8 @@ package com.huanshankeji.compose.material.ext import androidx.compose.runtime.Composable +import com.huanshankeji.compose.foundation.text.KeyboardActions +import com.huanshankeji.compose.foundation.text.KeyboardOptions import com.huanshankeji.compose.ui.Modifier /** @@ -20,6 +22,8 @@ expect fun TextField( */ leadingIcon: @Composable (() -> Unit)? = null, trailingIcon: @Composable (() -> Unit)? = null, + keyboardOptions: KeyboardOptions = KeyboardOptions.Default, + keyboardActions: KeyboardActions = KeyboardActions.Default, singleLine: Boolean = false ) @@ -36,6 +40,8 @@ expect fun OutlinedTextField( label: String? = null, leadingIcon: @Composable (() -> Unit)? = null, trailingIcon: @Composable (() -> Unit)? = null, + keyboardOptions: KeyboardOptions = KeyboardOptions.Default, + keyboardActions: KeyboardActions = KeyboardActions.Default, singleLine: Boolean = false ) @@ -46,5 +52,7 @@ expect fun TextArea( modifier: Modifier = Modifier, enabled: Boolean = true, label: String? = null, + keyboardOptions: KeyboardOptions = KeyboardOptions.Default, + keyboardActions: KeyboardActions = KeyboardActions.Default, lines: Int ) diff --git a/compose-multiplatform-material/src/jsMain/kotlin/com/huanshankeji/compose/material/ext/TextField.js.kt b/compose-multiplatform-material/src/jsMain/kotlin/com/huanshankeji/compose/material/ext/TextField.js.kt index 26872383..f23e6486 100644 --- a/compose-multiplatform-material/src/jsMain/kotlin/com/huanshankeji/compose/material/ext/TextField.js.kt +++ b/compose-multiplatform-material/src/jsMain/kotlin/com/huanshankeji/compose/material/ext/TextField.js.kt @@ -1,6 +1,9 @@ package com.huanshankeji.compose.material.ext import androidx.compose.runtime.Composable +import com.huanshankeji.compose.foundation.text.KeyboardActions +import com.huanshankeji.compose.foundation.text.KeyboardOptions +import com.huanshankeji.compose.foundation.text.attrsFrom import com.huanshankeji.compose.ui.Modifier import com.varabyte.kobweb.compose.ui.toAttrs import dev.petuska.kmdc.textfield.MDCTextArea @@ -16,7 +19,9 @@ fun CommonTextField( enabled: Boolean, label: String?, leadingIcon: @Composable (() -> Unit)?, - trailingIcon: @Composable (() -> Unit)? + trailingIcon: @Composable (() -> Unit)?, + keyboardOptions: KeyboardOptions, + keyboardActions: KeyboardActions ) = MDCTextField( value, @@ -27,6 +32,8 @@ fun CommonTextField( trailingIcon = trailingIcon?.let { { it() } }, attrs = modifier.platformModifier.toAttrs { onInput { onValueChange(it.value) } + + attrsFrom(keyboardOptions, keyboardActions) } ) @@ -39,9 +46,22 @@ actual fun TextField( label: String?, leadingIcon: @Composable (() -> Unit)?, trailingIcon: @Composable (() -> Unit)?, + keyboardOptions: KeyboardOptions, + keyboardActions: KeyboardActions, singleLine: Boolean ) = - CommonTextField(value, MDCTextFieldType.Filled, onValueChange, modifier, enabled, label, leadingIcon, trailingIcon) + CommonTextField( + value, + MDCTextFieldType.Filled, + onValueChange, + modifier, + enabled, + label, + leadingIcon, + trailingIcon, + keyboardOptions, + keyboardActions + ) @Composable actual fun OutlinedTextField( @@ -52,10 +72,21 @@ actual fun OutlinedTextField( label: String?, leadingIcon: @Composable (() -> Unit)?, trailingIcon: @Composable (() -> Unit)?, + keyboardOptions: KeyboardOptions, + keyboardActions: KeyboardActions, singleLine: Boolean ) = CommonTextField( - value, MDCTextFieldType.Outlined, onValueChange, modifier, enabled, label, leadingIcon, trailingIcon + value, + MDCTextFieldType.Outlined, + onValueChange, + modifier, + enabled, + label, + leadingIcon, + trailingIcon, + keyboardOptions, + keyboardActions ) @Composable @@ -65,6 +96,8 @@ actual fun TextArea( modifier: Modifier, enabled: Boolean, label: String?, + keyboardOptions: KeyboardOptions, + keyboardActions: KeyboardActions, lines: Int ) = MDCTextArea( diff --git a/compose-multiplatform-material3/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material3/ext/TextField.androidxCommon.kt b/compose-multiplatform-material3/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material3/ext/TextField.androidxCommon.kt index bcec783b..8518a670 100644 --- a/compose-multiplatform-material3/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material3/ext/TextField.androidxCommon.kt +++ b/compose-multiplatform-material3/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material3/ext/TextField.androidxCommon.kt @@ -2,6 +2,9 @@ package com.huanshankeji.compose.material3.ext import androidx.compose.material3.Text import androidx.compose.runtime.Composable +import com.huanshankeji.compose.foundation.text.KeyboardActions +import com.huanshankeji.compose.foundation.text.KeyboardOptions +import com.huanshankeji.compose.foundation.text.toPlatformValue import com.huanshankeji.compose.ui.Modifier // This function can be moved into a common file. @@ -23,6 +26,8 @@ actual fun TextField( suffix: String?, supportingText: String?, isError: Boolean, + keyboardOptions: KeyboardOptions, + keyboardActions: KeyboardActions, singleLine: Boolean, lines: Int ) = @@ -40,6 +45,8 @@ actual fun TextField( suffix = suffix.ToNullableTextComposable(), supportingText = supportingText.ToNullableTextComposable(), isError = isError, + keyboardOptions = keyboardOptions.toPlatformValue(), + keyboardActions = keyboardActions.toPlatformValue(), singleLine = singleLine, maxLines = lines, minLines = lines @@ -60,6 +67,8 @@ actual fun OutlinedTextField( suffix: String?, supportingText: String?, isError: Boolean, + keyboardOptions: KeyboardOptions, + keyboardActions: KeyboardActions, singleLine: Boolean, lines: Int ) = @@ -77,6 +86,8 @@ actual fun OutlinedTextField( suffix = suffix.ToNullableTextComposable(), supportingText = supportingText.ToNullableTextComposable(), isError = isError, + keyboardOptions = keyboardOptions.toPlatformValue(), + keyboardActions = keyboardActions.toPlatformValue(), singleLine = singleLine, maxLines = lines, minLines = lines diff --git a/compose-multiplatform-material3/src/commonMain/kotlin/com/huanshankeji/compose/material3/ext/TextField.kt b/compose-multiplatform-material3/src/commonMain/kotlin/com/huanshankeji/compose/material3/ext/TextField.kt index bdca9427..28eed6a7 100644 --- a/compose-multiplatform-material3/src/commonMain/kotlin/com/huanshankeji/compose/material3/ext/TextField.kt +++ b/compose-multiplatform-material3/src/commonMain/kotlin/com/huanshankeji/compose/material3/ext/TextField.kt @@ -1,10 +1,10 @@ package com.huanshankeji.compose.material3.ext import androidx.compose.runtime.Composable +import com.huanshankeji.compose.foundation.text.KeyboardActions +import com.huanshankeji.compose.foundation.text.KeyboardOptions import com.huanshankeji.compose.ui.Modifier -// TODO `KeyboardOptions` which relates to `InputMode` and `InputType` on JS, and `KeyboardActions` - @Composable expect fun TextField( value: String, @@ -20,6 +20,8 @@ expect fun TextField( suffix: String? = null, supportingText: String? = null, isError: Boolean = false, + keyboardOptions: KeyboardOptions = KeyboardOptions.Default, + keyboardActions: KeyboardActions = KeyboardActions.Default, singleLine: Boolean = false, lines: Int = 1 /* @@ -44,6 +46,8 @@ expect fun OutlinedTextField( suffix: String? = null, supportingText: String? = null, isError: Boolean = false, + keyboardOptions: KeyboardOptions = KeyboardOptions.Default, + keyboardActions: KeyboardActions = KeyboardActions.Default, singleLine: Boolean = false, lines: Int = 1 ) diff --git a/compose-multiplatform-material3/src/jsMain/kotlin/com/huanshankeji/compose/material3/ext/TextField.js.kt b/compose-multiplatform-material3/src/jsMain/kotlin/com/huanshankeji/compose/material3/ext/TextField.js.kt index fc430a5d..f8597dc7 100644 --- a/compose-multiplatform-material3/src/jsMain/kotlin/com/huanshankeji/compose/material3/ext/TextField.js.kt +++ b/compose-multiplatform-material3/src/jsMain/kotlin/com/huanshankeji/compose/material3/ext/TextField.js.kt @@ -1,6 +1,9 @@ package com.huanshankeji.compose.material3.ext import androidx.compose.runtime.Composable +import com.huanshankeji.compose.foundation.text.KeyboardActions +import com.huanshankeji.compose.foundation.text.KeyboardOptions +import com.huanshankeji.compose.foundation.text.attrsFrom import com.huanshankeji.compose.html.material3.MdFilledTextField import com.huanshankeji.compose.html.material3.MdOutlinedTextField import com.huanshankeji.compose.html.material3.MdTextFieldScope @@ -16,10 +19,13 @@ import org.w3c.dom.HTMLElement import com.varabyte.kobweb.compose.ui.Modifier as PlatformModifier private fun Modifier.toTextFieldAttrs( - onValueChange: (String) -> Unit + onValueChange: (String) -> Unit, keyboardOptions: KeyboardOptions, keyboardActions: KeyboardActions, ): AttrsScope.() -> Unit = platformModifier.toAttrs { onInput { onValueChange(it.target.value) } + + // TODO `keyboardOptions.imeAction` is not working because `enterkeyhint` is not passed to the underlying `input`. + attrsFrom(keyboardOptions, keyboardActions) } private fun TextFieldContent(): @Composable MdTextFieldScope.() -> Unit = { @@ -44,6 +50,8 @@ actual fun TextField( suffix: String?, supportingText: String?, isError: Boolean, + keyboardOptions: KeyboardOptions, + keyboardActions: KeyboardActions, singleLine: Boolean, lines: Int ) = @@ -59,11 +67,10 @@ actual fun TextField( hasTrailingIcon = trailingIcon?.let { true }, supportingText = supportingText, rows = if (singleLine) null else lines, - //inputMode = TODO(), placeholder = placeholder, readOnly = readOnly.isTrueOrNull(), - attrs = modifier.toTextFieldAttrs(onValueChange), + attrs = modifier.toTextFieldAttrs(onValueChange, keyboardOptions, keyboardActions), content = TextFieldContent() ) @@ -83,6 +90,8 @@ actual fun OutlinedTextField( suffix: String?, supportingText: String?, isError: Boolean, + keyboardOptions: KeyboardOptions, + keyboardActions: KeyboardActions, singleLine: Boolean, lines: Int ) = @@ -98,10 +107,9 @@ actual fun OutlinedTextField( hasTrailingIcon = trailingIcon?.let { true }, supportingText = supportingText, rows = if (singleLine) null else lines, - //inputMode = TODO(), placeholder = placeholder, readOnly = readOnly.isTrueOrNull(), - attrs = modifier.toTextFieldAttrs(onValueChange), + attrs = modifier.toTextFieldAttrs(onValueChange, keyboardOptions, keyboardActions), content = TextFieldContent() ) diff --git a/demo/src/commonMain/kotlin/com/huanshankeji/compose/material/demo/Material2.kt b/demo/src/commonMain/kotlin/com/huanshankeji/compose/material/demo/Material2.kt index 22b9964a..d5ecbc6b 100644 --- a/demo/src/commonMain/kotlin/com/huanshankeji/compose/material/demo/Material2.kt +++ b/demo/src/commonMain/kotlin/com/huanshankeji/compose/material/demo/Material2.kt @@ -11,6 +11,8 @@ import com.huanshankeji.compose.foundation.layout.Box import com.huanshankeji.compose.foundation.layout.Column import com.huanshankeji.compose.foundation.layout.Row import com.huanshankeji.compose.foundation.layout.RowScope +import com.huanshankeji.compose.foundation.text.KeyboardOptions +import com.huanshankeji.compose.foundation.text.input.ImeAction import com.huanshankeji.compose.layout.height import com.huanshankeji.compose.layout.padding import com.huanshankeji.compose.layout.size @@ -120,6 +122,7 @@ fun Material2() { label = "Demo text field", leadingIcon = { Icon(Icons.Default.Add, null) }, trailingIcon = { Icon(Icons.Default.Menu, null) }, + keyboardOptions = KeyboardOptions(imeAction = ImeAction.Search), singleLine = true ) TextArea(text, { text = it }, label = "Demo text field", lines = 3) diff --git a/demo/src/commonMain/kotlin/com/huanshankeji/compose/material/demo/Material3.kt b/demo/src/commonMain/kotlin/com/huanshankeji/compose/material/demo/Material3.kt index e3b17843..ce2f7c6b 100644 --- a/demo/src/commonMain/kotlin/com/huanshankeji/compose/material/demo/Material3.kt +++ b/demo/src/commonMain/kotlin/com/huanshankeji/compose/material/demo/Material3.kt @@ -4,7 +4,9 @@ import androidx.compose.runtime.* import com.huanshankeji.compose.foundation.layout.Column import com.huanshankeji.compose.foundation.layout.Row import com.huanshankeji.compose.foundation.layout.RowScope +import com.huanshankeji.compose.foundation.text.KeyboardOptions import com.huanshankeji.compose.foundation.text.ext.InlineBasicText +import com.huanshankeji.compose.foundation.text.input.ImeAction import com.huanshankeji.compose.material3.Checkbox import com.huanshankeji.compose.material3.Switch import com.huanshankeji.compose.material3.ext.* @@ -37,6 +39,6 @@ fun Material3() { var text by remember { mutableStateOf("") } TextField(text, { text = it }) - OutlinedTextField(text, { text = it }) + OutlinedTextField(text, { text = it }, keyboardOptions = KeyboardOptions(imeAction = ImeAction.Search)) // TODO } } From 668a49459bc998205aba7fb982c8885bd62365ab Mon Sep 17 00:00:00 2001 From: Shreck Ye Date: Tue, 30 Apr 2024 03:55:34 +0800 Subject: [PATCH 46/75] Try fixing the bug that the texts are out of sync as mentioned in commit c5fce3b217cf01c82f03d0bbb4ce218846d5751c but fail Learn about the `bubbles` and `composed` property and investigate the `input` and `change` event objects. From 649fdc01c5a06ab6e63dc7b53f6d0949675b61be Mon Sep 17 00:00:00 2001 From: Shreck Ye Date: Tue, 30 Apr 2024 04:20:51 +0800 Subject: [PATCH 47/75] Test more text field parameters in the demo --- .../compose/material/demo/Material2.kt | 11 +++++- .../compose/material/demo/Material3.kt | 35 +++++++++++++++++-- 2 files changed, 43 insertions(+), 3 deletions(-) diff --git a/demo/src/commonMain/kotlin/com/huanshankeji/compose/material/demo/Material2.kt b/demo/src/commonMain/kotlin/com/huanshankeji/compose/material/demo/Material2.kt index d5ecbc6b..664291b7 100644 --- a/demo/src/commonMain/kotlin/com/huanshankeji/compose/material/demo/Material2.kt +++ b/demo/src/commonMain/kotlin/com/huanshankeji/compose/material/demo/Material2.kt @@ -11,8 +11,11 @@ import com.huanshankeji.compose.foundation.layout.Box import com.huanshankeji.compose.foundation.layout.Column import com.huanshankeji.compose.foundation.layout.Row import com.huanshankeji.compose.foundation.layout.RowScope +import com.huanshankeji.compose.foundation.text.KeyboardActions import com.huanshankeji.compose.foundation.text.KeyboardOptions import com.huanshankeji.compose.foundation.text.input.ImeAction +import com.huanshankeji.compose.foundation.text.input.KeyboardCapitalization +import com.huanshankeji.compose.foundation.text.input.KeyboardType import com.huanshankeji.compose.layout.height import com.huanshankeji.compose.layout.padding import com.huanshankeji.compose.layout.size @@ -115,6 +118,7 @@ fun Material2() { label = "Demo text field", leadingIcon = { Icon(Icons.Default.Add, null) }, trailingIcon = { Icon(Icons.Default.Menu, null) }, + keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number), singleLine = true ) OutlinedTextField( @@ -122,7 +126,12 @@ fun Material2() { label = "Demo text field", leadingIcon = { Icon(Icons.Default.Add, null) }, trailingIcon = { Icon(Icons.Default.Menu, null) }, - keyboardOptions = KeyboardOptions(imeAction = ImeAction.Search), + keyboardOptions = KeyboardOptions( + KeyboardCapitalization.Words, true, imeAction = ImeAction.Search + ), + keyboardActions = KeyboardActions { + println("keyboard actions with: $text") + }, singleLine = true ) TextArea(text, { text = it }, label = "Demo text field", lines = 3) diff --git a/demo/src/commonMain/kotlin/com/huanshankeji/compose/material/demo/Material3.kt b/demo/src/commonMain/kotlin/com/huanshankeji/compose/material/demo/Material3.kt index ce2f7c6b..a6f9316b 100644 --- a/demo/src/commonMain/kotlin/com/huanshankeji/compose/material/demo/Material3.kt +++ b/demo/src/commonMain/kotlin/com/huanshankeji/compose/material/demo/Material3.kt @@ -4,9 +4,12 @@ import androidx.compose.runtime.* import com.huanshankeji.compose.foundation.layout.Column import com.huanshankeji.compose.foundation.layout.Row import com.huanshankeji.compose.foundation.layout.RowScope +import com.huanshankeji.compose.foundation.text.KeyboardActions import com.huanshankeji.compose.foundation.text.KeyboardOptions import com.huanshankeji.compose.foundation.text.ext.InlineBasicText import com.huanshankeji.compose.foundation.text.input.ImeAction +import com.huanshankeji.compose.foundation.text.input.KeyboardCapitalization +import com.huanshankeji.compose.foundation.text.input.KeyboardType import com.huanshankeji.compose.material3.Checkbox import com.huanshankeji.compose.material3.Switch import com.huanshankeji.compose.material3.ext.* @@ -38,7 +41,35 @@ fun Material3() { } var text by remember { mutableStateOf("") } - TextField(text, { text = it }) - OutlinedTextField(text, { text = it }, keyboardOptions = KeyboardOptions(imeAction = ImeAction.Search)) // TODO + val label = "label" + val placeholder = "placeholder" + val prefix = "prefix" + val suffix = "suffix" + val supportingText = "supporting text" + TextField( + text, + { text = it }, + label = label, + placeholder = placeholder, + prefix = prefix, + suffix = suffix, + supportingText = supportingText, + keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number) + ) + OutlinedTextField( + text, + { text = it }, + label = label, + placeholder = placeholder, + prefix = prefix, + suffix = suffix, + supportingText = supportingText, + keyboardOptions = KeyboardOptions( + KeyboardCapitalization.Words, true, imeAction = ImeAction.Search + ), + keyboardActions = KeyboardActions { + println("keyboard actions with: $text") + } + ) } } From 460be1e9e5dcf02e7b56dbbfe455397481a7a908 Mon Sep 17 00:00:00 2001 From: Shreck Ye Date: Tue, 30 Apr 2024 17:34:09 +0800 Subject: [PATCH 48/75] Check listening for `input` events on text fields --- .../com/huanshankeji/compose/material3/ext/TextField.js.kt | 1 + 1 file changed, 1 insertion(+) diff --git a/compose-multiplatform-material3/src/jsMain/kotlin/com/huanshankeji/compose/material3/ext/TextField.js.kt b/compose-multiplatform-material3/src/jsMain/kotlin/com/huanshankeji/compose/material3/ext/TextField.js.kt index f8597dc7..a927e184 100644 --- a/compose-multiplatform-material3/src/jsMain/kotlin/com/huanshankeji/compose/material3/ext/TextField.js.kt +++ b/compose-multiplatform-material3/src/jsMain/kotlin/com/huanshankeji/compose/material3/ext/TextField.js.kt @@ -22,6 +22,7 @@ private fun Modifier.toTextFieldAttrs( onValueChange: (String) -> Unit, keyboardOptions: KeyboardOptions, keyboardActions: KeyboardActions, ): AttrsScope.() -> Unit = platformModifier.toAttrs { + // see https://stackoverflow.com/questions/574941/best-way-to-track-onchange-as-you-type-in-input-type-text onInput { onValueChange(it.target.value) } // TODO `keyboardOptions.imeAction` is not working because `enterkeyhint` is not passed to the underlying `input`. From b64cc6bf4d4f546f2a08b0f9a0c079796af0b21a Mon Sep 17 00:00:00 2001 From: Shreck Ye Date: Thu, 2 May 2024 18:21:47 +0800 Subject: [PATCH 49/75] Add the Material 3 `Icon` composable, Refactor the `com.huanshankeji.compose.material.icons` package into a common module that works for both Material 2 and Material 3 as how it works in `androidx.compose.material`, and improve the text field composables with work with the new icon APIs --- .../main/kotlin/VersionsAndDependencies.kt | 4 +- .../compose/ContentDescription.kt | 12 ++ .../huanshankeji/compose/ui/Modifier.js.kt | 5 +- .../build.gradle.kts | 36 ++++ .../material/icons/Icons.androidxCommon.kt | 0 .../icons/filled/Icons.androidxCommon.kt | 0 .../compose/material/icons/Icons.kt | 0 .../compose/material/icons/filled/Icons.kt | 0 .../compose/material/icons/Icons.js.kt | 3 + .../compose/material/icons/filled/Icons.js.kt | 8 + .../build.gradle.kts | 1 + .../material/ext/TextField.androidxCommon.kt | 52 +++++ .../compose/material/ext/TextField.kt | 37 ++++ .../huanshankeji/compose/material/Icon.js.kt | 14 +- .../compose/material/ext/TextField.js.kt | 129 +++++++++++- .../material/ext/TopAppBarScaffold.js.kt | 6 +- .../compose/material/icons/Icons.js.kt | 5 - .../compose/material/icons/IconsMdc.kt | 8 + .../compose/material/icons/filled/Icons.js.kt | 9 - .../build.gradle.kts | 1 + .../compose/material3/Icon.androidxCommon.kt | 13 ++ .../material3/ext/TextField.androidxCommon.kt | 171 ++++++++++++++++ .../huanshankeji/compose/material3/Icon.kt | 13 ++ .../compose/material3/ext/TextField.kt | 94 +++++++++ .../huanshankeji/compose/material3/Icon.js.kt | 18 ++ .../compose/material3/ext/TextField.js.kt | 186 +++++++++++++++++- .../compose/material/demo/Material2.kt | 12 +- .../compose/material/demo/Material3.kt | 11 +- demo/src/jsMain/resources/index.html | 2 + settings.gradle.kts | 1 + 30 files changed, 799 insertions(+), 52 deletions(-) create mode 100644 compose-multiplatform-common/src/jsMain/kotlin/com/huanshankeji/compose/ContentDescription.kt create mode 100644 compose-multiplatform-material-icons-core/build.gradle.kts rename {compose-multiplatform-material => compose-multiplatform-material-icons-core}/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material/icons/Icons.androidxCommon.kt (100%) rename {compose-multiplatform-material => compose-multiplatform-material-icons-core}/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material/icons/filled/Icons.androidxCommon.kt (100%) rename {compose-multiplatform-material => compose-multiplatform-material-icons-core}/src/commonMain/kotlin/com/huanshankeji/compose/material/icons/Icons.kt (100%) rename {compose-multiplatform-material => compose-multiplatform-material-icons-core}/src/commonMain/kotlin/com/huanshankeji/compose/material/icons/filled/Icons.kt (100%) create mode 100644 compose-multiplatform-material-icons-core/src/jsMain/kotlin/com/huanshankeji/compose/material/icons/Icons.js.kt create mode 100644 compose-multiplatform-material-icons-core/src/jsMain/kotlin/com/huanshankeji/compose/material/icons/filled/Icons.js.kt delete mode 100644 compose-multiplatform-material/src/jsMain/kotlin/com/huanshankeji/compose/material/icons/Icons.js.kt create mode 100644 compose-multiplatform-material/src/jsMain/kotlin/com/huanshankeji/compose/material/icons/IconsMdc.kt delete mode 100644 compose-multiplatform-material/src/jsMain/kotlin/com/huanshankeji/compose/material/icons/filled/Icons.js.kt create mode 100644 compose-multiplatform-material3/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material3/Icon.androidxCommon.kt create mode 100644 compose-multiplatform-material3/src/commonMain/kotlin/com/huanshankeji/compose/material3/Icon.kt create mode 100644 compose-multiplatform-material3/src/jsMain/kotlin/com/huanshankeji/compose/material3/Icon.js.kt diff --git a/buildSrc/src/main/kotlin/VersionsAndDependencies.kt b/buildSrc/src/main/kotlin/VersionsAndDependencies.kt index b8e6a73f..2622872f 100644 --- a/buildSrc/src/main/kotlin/VersionsAndDependencies.kt +++ b/buildSrc/src/main/kotlin/VersionsAndDependencies.kt @@ -1,7 +1,9 @@ +import org.jetbrains.compose.ComposeBuildConfig + val projectVersion = "0.3.0-SNAPSHOT" object DependencyVersions { - val composeMultiplatform = "1.6.2" // manually specified for "ui-unit" + const val composeMultiplatform = ComposeBuildConfig.composeVersion // for "ui-unit" val kobweb = "0.17.3" val huanshankejiComposeHtml = "0.3.0-SNAPSHOT" // TODO don't use a snapshot in a main branch val kmdc = "0.1.2" diff --git a/compose-multiplatform-common/src/jsMain/kotlin/com/huanshankeji/compose/ContentDescription.kt b/compose-multiplatform-common/src/jsMain/kotlin/com/huanshankeji/compose/ContentDescription.kt new file mode 100644 index 00000000..3782e2fb --- /dev/null +++ b/compose-multiplatform-common/src/jsMain/kotlin/com/huanshankeji/compose/ContentDescription.kt @@ -0,0 +1,12 @@ +package com.huanshankeji.compose + +import org.jetbrains.compose.web.attributes.AttrsScope + +fun AttrsScope<*>.contentDescription(contentDescription: String?) = + contentDescription?.let { + // aria-label's semantics don't seem to meet the requirements perfectly because it labels an interactive element + // see: https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Attributes/aria-label, https://stackoverflow.com/questions/22039910/what-is-aria-label-and-how-should-i-use-it + //attr("aria-label", it) + + title(it) + } diff --git a/compose-multiplatform-common/src/jsMain/kotlin/com/huanshankeji/compose/ui/Modifier.js.kt b/compose-multiplatform-common/src/jsMain/kotlin/com/huanshankeji/compose/ui/Modifier.js.kt index fb980ac4..f2878068 100644 --- a/compose-multiplatform-common/src/jsMain/kotlin/com/huanshankeji/compose/ui/Modifier.js.kt +++ b/compose-multiplatform-common/src/jsMain/kotlin/com/huanshankeji/compose/ui/Modifier.js.kt @@ -29,4 +29,7 @@ actual interface Modifier { actual companion object : Modifier { override val platformModifier = PlatformModifier } -} \ No newline at end of file +} + +fun PlatformModifier.toCommonModifier() = + Modifier.Impl(this) diff --git a/compose-multiplatform-material-icons-core/build.gradle.kts b/compose-multiplatform-material-icons-core/build.gradle.kts new file mode 100644 index 00000000..4d75f71c --- /dev/null +++ b/compose-multiplatform-material-icons-core/build.gradle.kts @@ -0,0 +1,36 @@ +import com.huanshankeji.team.`Shreck Ye` +import com.huanshankeji.team.pomForTeamDefaultOpenSource + +plugins { + `lib-conventions` +} + +kotlin { + sourceSets { + /* + Use `implementation`. See: + https://github.com/JetBrains/compose-multiplatform-core/blob/jb-main/compose/material/material-icons-core/build.gradle + https://android.googlesource.com/platform/frameworks/support/+/refs/heads/androidx-main/compose/material/material-icons-core/build.gradle + */ + commonMain { + dependencies { + implementation(compose.runtime) + } + } + androidxCommonMain { + dependencies { + api("org.jetbrains.compose.material:material-icons-extended:${DependencyVersions.composeMultiplatform}") + } + } + } +} + +publishing.publications.withType { + pomForTeamDefaultOpenSource( + project, + "Compose Multiplatform Material core Icon wrappers", + "Compose Multiplatform Material Design core Icon wrappers for `androidx.compose` and Compose HTML" + ) { + `Shreck Ye`() + } +} diff --git a/compose-multiplatform-material/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material/icons/Icons.androidxCommon.kt b/compose-multiplatform-material-icons-core/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material/icons/Icons.androidxCommon.kt similarity index 100% rename from compose-multiplatform-material/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material/icons/Icons.androidxCommon.kt rename to compose-multiplatform-material-icons-core/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material/icons/Icons.androidxCommon.kt diff --git a/compose-multiplatform-material/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material/icons/filled/Icons.androidxCommon.kt b/compose-multiplatform-material-icons-core/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material/icons/filled/Icons.androidxCommon.kt similarity index 100% rename from compose-multiplatform-material/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material/icons/filled/Icons.androidxCommon.kt rename to compose-multiplatform-material-icons-core/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material/icons/filled/Icons.androidxCommon.kt diff --git a/compose-multiplatform-material/src/commonMain/kotlin/com/huanshankeji/compose/material/icons/Icons.kt b/compose-multiplatform-material-icons-core/src/commonMain/kotlin/com/huanshankeji/compose/material/icons/Icons.kt similarity index 100% rename from compose-multiplatform-material/src/commonMain/kotlin/com/huanshankeji/compose/material/icons/Icons.kt rename to compose-multiplatform-material-icons-core/src/commonMain/kotlin/com/huanshankeji/compose/material/icons/Icons.kt diff --git a/compose-multiplatform-material/src/commonMain/kotlin/com/huanshankeji/compose/material/icons/filled/Icons.kt b/compose-multiplatform-material-icons-core/src/commonMain/kotlin/com/huanshankeji/compose/material/icons/filled/Icons.kt similarity index 100% rename from compose-multiplatform-material/src/commonMain/kotlin/com/huanshankeji/compose/material/icons/filled/Icons.kt rename to compose-multiplatform-material-icons-core/src/commonMain/kotlin/com/huanshankeji/compose/material/icons/filled/Icons.kt diff --git a/compose-multiplatform-material-icons-core/src/jsMain/kotlin/com/huanshankeji/compose/material/icons/Icons.js.kt b/compose-multiplatform-material-icons-core/src/jsMain/kotlin/com/huanshankeji/compose/material/icons/Icons.js.kt new file mode 100644 index 00000000..bfca4078 --- /dev/null +++ b/compose-multiplatform-material-icons-core/src/jsMain/kotlin/com/huanshankeji/compose/material/icons/Icons.js.kt @@ -0,0 +1,3 @@ +package com.huanshankeji.compose.material.icons + +actual class Icon(val name: String) diff --git a/compose-multiplatform-material-icons-core/src/jsMain/kotlin/com/huanshankeji/compose/material/icons/filled/Icons.js.kt b/compose-multiplatform-material-icons-core/src/jsMain/kotlin/com/huanshankeji/compose/material/icons/filled/Icons.js.kt new file mode 100644 index 00000000..422a231b --- /dev/null +++ b/compose-multiplatform-material-icons-core/src/jsMain/kotlin/com/huanshankeji/compose/material/icons/filled/Icons.js.kt @@ -0,0 +1,8 @@ +package com.huanshankeji.compose.material.icons.filled + +import com.huanshankeji.compose.material.icons.Icon +import com.huanshankeji.compose.material.icons.Icons + +actual val Icons.Filled.Add: Icon get() = Icon("add") +actual val Icons.Filled.Menu: Icon get() = Icon("menu") +actual val Icons.Filled.Search: Icon get() = Icon("search") diff --git a/compose-multiplatform-material/build.gradle.kts b/compose-multiplatform-material/build.gradle.kts index a9f81df9..c2781d50 100644 --- a/compose-multiplatform-material/build.gradle.kts +++ b/compose-multiplatform-material/build.gradle.kts @@ -17,6 +17,7 @@ kotlin { api(compose.runtime) implementation("org.jetbrains.compose.annotation-internal:annotation:${DependencyVersions.composeMultiplatform}") api(project(":compose-multiplatform-common")) + api(project(":compose-multiplatform-material-icons-core")) //compileOnly(compose.material) // for KDoc element links only } } diff --git a/compose-multiplatform-material/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material/ext/TextField.androidxCommon.kt b/compose-multiplatform-material/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material/ext/TextField.androidxCommon.kt index 5fe95ec7..6af5c925 100644 --- a/compose-multiplatform-material/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material/ext/TextField.androidxCommon.kt +++ b/compose-multiplatform-material/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material/ext/TextField.androidxCommon.kt @@ -4,7 +4,9 @@ import androidx.compose.runtime.Composable import com.huanshankeji.compose.foundation.text.KeyboardActions import com.huanshankeji.compose.foundation.text.KeyboardOptions import com.huanshankeji.compose.foundation.text.toPlatformValue +import com.huanshankeji.compose.material.Icon import com.huanshankeji.compose.material.Text +import com.huanshankeji.compose.material.icons.Icon import com.huanshankeji.compose.ui.Modifier @Composable @@ -33,6 +35,31 @@ actual fun TextField( singleLine = singleLine ) +@Composable +actual fun TextFieldWithMaterialIcons( + value: String, + onValueChange: (String) -> Unit, + modifier: Modifier, + enabled: Boolean, + label: String?, + leadingIcon: Icon?, + trailingIcon: Icon?, + keyboardOptions: KeyboardOptions, + keyboardActions: KeyboardActions, + singleLine: Boolean +) = + TextField( + value, + onValueChange, + modifier, + enabled, + label, + leadingIcon?.let { { Icon(it, null) } }, + trailingIcon?.let { { Icon(it, null) } }, + keyboardOptions, keyboardActions, singleLine + ) + + @Composable actual fun OutlinedTextField( value: String, @@ -59,6 +86,31 @@ actual fun OutlinedTextField( singleLine = singleLine ) +@Composable +actual fun OutlinedTextFieldWithMaterialIcons( + value: String, + onValueChange: (String) -> Unit, + modifier: Modifier, + enabled: Boolean, + label: String?, + leadingIcon: Icon?, + trailingIcon: Icon?, + keyboardOptions: KeyboardOptions, + keyboardActions: KeyboardActions, + singleLine: Boolean +) = + OutlinedTextField( + value, + onValueChange, + modifier, + enabled, + label, + leadingIcon?.let { { Icon(it, null) } }, + trailingIcon?.let { { Icon(it, null) } }, + keyboardOptions, keyboardActions, singleLine + ) + + @Composable actual fun TextArea( value: String, diff --git a/compose-multiplatform-material/src/commonMain/kotlin/com/huanshankeji/compose/material/ext/TextField.kt b/compose-multiplatform-material/src/commonMain/kotlin/com/huanshankeji/compose/material/ext/TextField.kt index b5519b4f..17d19b69 100644 --- a/compose-multiplatform-material/src/commonMain/kotlin/com/huanshankeji/compose/material/ext/TextField.kt +++ b/compose-multiplatform-material/src/commonMain/kotlin/com/huanshankeji/compose/material/ext/TextField.kt @@ -3,6 +3,7 @@ package com.huanshankeji.compose.material.ext import androidx.compose.runtime.Composable import com.huanshankeji.compose.foundation.text.KeyboardActions import com.huanshankeji.compose.foundation.text.KeyboardOptions +import com.huanshankeji.compose.material.icons.Icon import com.huanshankeji.compose.ui.Modifier /** @@ -27,6 +28,24 @@ expect fun TextField( singleLine: Boolean = false ) +/** + * @see TextField + */ +@Composable +expect fun TextFieldWithMaterialIcons( + value: String, + onValueChange: (String) -> Unit, + modifier: Modifier = Modifier, + enabled: Boolean = true, + label: String? = null, + leadingIcon: Icon? = null, + trailingIcon: Icon? = null, + keyboardOptions: KeyboardOptions = KeyboardOptions.Default, + keyboardActions: KeyboardActions = KeyboardActions.Default, + singleLine: Boolean = false +) + + // maybe put in `OutlinedTextField.kt` /** * @param singleLine on JS it's always single line. @@ -45,6 +64,24 @@ expect fun OutlinedTextField( singleLine: Boolean = false ) +/** + * @see OutlinedTextField + */ +@Composable +expect fun OutlinedTextFieldWithMaterialIcons( + value: String, + onValueChange: (String) -> Unit, + modifier: Modifier = Modifier, + enabled: Boolean = true, + label: String? = null, + leadingIcon: Icon? = null, + trailingIcon: Icon? = null, + keyboardOptions: KeyboardOptions = KeyboardOptions.Default, + keyboardActions: KeyboardActions = KeyboardActions.Default, + singleLine: Boolean = false +) + + @Composable expect fun TextArea( value: String, diff --git a/compose-multiplatform-material/src/jsMain/kotlin/com/huanshankeji/compose/material/Icon.js.kt b/compose-multiplatform-material/src/jsMain/kotlin/com/huanshankeji/compose/material/Icon.js.kt index 1bbb9399..b4dfc4ed 100644 --- a/compose-multiplatform-material/src/jsMain/kotlin/com/huanshankeji/compose/material/Icon.js.kt +++ b/compose-multiplatform-material/src/jsMain/kotlin/com/huanshankeji/compose/material/Icon.js.kt @@ -1,26 +1,18 @@ package com.huanshankeji.compose.material import androidx.compose.runtime.Composable +import com.huanshankeji.compose.contentDescription import com.huanshankeji.compose.material.icons.Icon +import com.huanshankeji.compose.material.icons.toMDCIcon import com.huanshankeji.compose.ui.Modifier import com.varabyte.kobweb.compose.ui.toAttrs import dev.petuska.kmdcx.icons.MDCIconSpan -import org.jetbrains.compose.web.attributes.AttrsScope /** * There is often a better alternative of adding the CSS rule to the parent element to using this composable directly. */ @Composable actual fun Icon(icon: Icon, contentDescription: String?, modifier: Modifier) = - MDCIconSpan(icon.mdcIcon, attrs = modifier.platformModifier.toAttrs { + MDCIconSpan(icon.toMDCIcon(), attrs = modifier.platformModifier.toAttrs { contentDescription(contentDescription) }) - -internal fun AttrsScope<*>.contentDescription(contentDescription: String?) = - contentDescription?.let { - // aria-label's semantics don't seem to meet the requirements perfectly because it labels an interactive element - // see: https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Attributes/aria-label, https://stackoverflow.com/questions/22039910/what-is-aria-label-and-how-should-i-use-it - //attr("aria-label", it) - - title(it) - } diff --git a/compose-multiplatform-material/src/jsMain/kotlin/com/huanshankeji/compose/material/ext/TextField.js.kt b/compose-multiplatform-material/src/jsMain/kotlin/com/huanshankeji/compose/material/ext/TextField.js.kt index f23e6486..da66fdd4 100644 --- a/compose-multiplatform-material/src/jsMain/kotlin/com/huanshankeji/compose/material/ext/TextField.js.kt +++ b/compose-multiplatform-material/src/jsMain/kotlin/com/huanshankeji/compose/material/ext/TextField.js.kt @@ -4,22 +4,29 @@ import androidx.compose.runtime.Composable import com.huanshankeji.compose.foundation.text.KeyboardActions import com.huanshankeji.compose.foundation.text.KeyboardOptions import com.huanshankeji.compose.foundation.text.attrsFrom +import com.huanshankeji.compose.material.icons.Icon import com.huanshankeji.compose.ui.Modifier import com.varabyte.kobweb.compose.ui.toAttrs +import dev.petuska.kmdc.core.MDCContent import dev.petuska.kmdc.textfield.MDCTextArea import dev.petuska.kmdc.textfield.MDCTextField +import dev.petuska.kmdc.textfield.MDCTextFieldScope import dev.petuska.kmdc.textfield.MDCTextFieldType +import dev.petuska.kmdc.textfield.icon.MDCTextFieldLeadingIcon +import dev.petuska.kmdc.textfield.icon.MDCTextFieldTrailingIcon +import dev.petuska.kmdcx.icons.mdcIcon +import org.jetbrains.compose.web.dom.Text @Composable -fun CommonTextField( +fun CommonTextFieldWithMDCContentIcons( value: String, type: MDCTextFieldType, onValueChange: (String) -> Unit, modifier: Modifier, enabled: Boolean, label: String?, - leadingIcon: @Composable (() -> Unit)?, - trailingIcon: @Composable (() -> Unit)?, + leadingIcon: MDCContent? = null, + trailingIcon: MDCContent? = null, keyboardOptions: KeyboardOptions, keyboardActions: KeyboardActions ) = @@ -28,8 +35,8 @@ fun CommonTextField( type, !enabled, label, - leadingIcon = leadingIcon?.let { { it() } }, - trailingIcon = trailingIcon?.let { { it() } }, + leadingIcon = leadingIcon, + trailingIcon = trailingIcon, attrs = modifier.platformModifier.toAttrs { onInput { onValueChange(it.value) } @@ -37,6 +44,60 @@ fun CommonTextField( } ) +@Composable +fun CommonTextFieldWithIconsLikeAndroidx( + value: String, + type: MDCTextFieldType, + onValueChange: (String) -> Unit, + modifier: Modifier, + enabled: Boolean, + label: String?, + leadingIcon: @Composable (() -> Unit)?, + trailingIcon: @Composable (() -> Unit)?, + keyboardOptions: KeyboardOptions, + keyboardActions: KeyboardActions +) = + CommonTextFieldWithMDCContentIcons( + value, + type, + onValueChange, + modifier, + enabled, + label, + leadingIcon?.let { { it() } }, + trailingIcon?.let { { it() } }, + keyboardOptions, + keyboardActions + ) + +@Composable +fun CommonTextFieldWithMaterialIcons( + value: String, + type: MDCTextFieldType, + onValueChange: (String) -> Unit, + modifier: Modifier, + enabled: Boolean, + label: String?, + leadingIcon: Icon?, + trailingIcon: Icon?, + keyboardOptions: KeyboardOptions, + keyboardActions: KeyboardActions +) = + CommonTextFieldWithMDCContentIcons( + value, + type, + onValueChange, + modifier, + enabled, + label, + // see https://github.com/mpetuska/kmdc/blob/master/sandbox/src/jsMain/showcases/MDCTextField.kt + leadingIcon?.let { { MDCTextFieldLeadingIcon(attrs = { mdcIcon() }) { Text(it.name) } } }, + trailingIcon?.let { { MDCTextFieldTrailingIcon(attrs = { mdcIcon() }) { Text(it.name) } } }, + keyboardOptions, + keyboardActions + ) + + @Composable actual fun TextField( value: String, @@ -50,7 +111,7 @@ actual fun TextField( keyboardActions: KeyboardActions, singleLine: Boolean ) = - CommonTextField( + CommonTextFieldWithIconsLikeAndroidx( value, MDCTextFieldType.Filled, onValueChange, @@ -63,6 +124,33 @@ actual fun TextField( keyboardActions ) +@Composable +actual fun TextFieldWithMaterialIcons( + value: String, + onValueChange: (String) -> Unit, + modifier: Modifier, + enabled: Boolean, + label: String?, + leadingIcon: Icon?, + trailingIcon: Icon?, + keyboardOptions: KeyboardOptions, + keyboardActions: KeyboardActions, + singleLine: Boolean +) = + CommonTextFieldWithMaterialIcons( + value, + MDCTextFieldType.Filled, + onValueChange, + modifier, + enabled, + label, + leadingIcon, + trailingIcon, + keyboardOptions, + keyboardActions + ) + + @Composable actual fun OutlinedTextField( value: String, @@ -76,7 +164,7 @@ actual fun OutlinedTextField( keyboardActions: KeyboardActions, singleLine: Boolean ) = - CommonTextField( + CommonTextFieldWithIconsLikeAndroidx( value, MDCTextFieldType.Outlined, onValueChange, @@ -89,6 +177,33 @@ actual fun OutlinedTextField( keyboardActions ) +@Composable +actual fun OutlinedTextFieldWithMaterialIcons( + value: String, + onValueChange: (String) -> Unit, + modifier: Modifier, + enabled: Boolean, + label: String?, + leadingIcon: Icon?, + trailingIcon: Icon?, + keyboardOptions: KeyboardOptions, + keyboardActions: KeyboardActions, + singleLine: Boolean +) = + CommonTextFieldWithMaterialIcons( + value, + MDCTextFieldType.Outlined, + onValueChange, + modifier, + enabled, + label, + leadingIcon, + trailingIcon, + keyboardOptions, + keyboardActions + ) + + @Composable actual fun TextArea( value: String, diff --git a/compose-multiplatform-material/src/jsMain/kotlin/com/huanshankeji/compose/material/ext/TopAppBarScaffold.js.kt b/compose-multiplatform-material/src/jsMain/kotlin/com/huanshankeji/compose/material/ext/TopAppBarScaffold.js.kt index 6a790942..93479b63 100644 --- a/compose-multiplatform-material/src/jsMain/kotlin/com/huanshankeji/compose/material/ext/TopAppBarScaffold.js.kt +++ b/compose-multiplatform-material/src/jsMain/kotlin/com/huanshankeji/compose/material/ext/TopAppBarScaffold.js.kt @@ -1,7 +1,7 @@ package com.huanshankeji.compose.material.ext import androidx.compose.runtime.Composable -import com.huanshankeji.compose.material.contentDescription +import com.huanshankeji.compose.contentDescription import com.huanshankeji.compose.material.icons.Icon import com.huanshankeji.compose.ui.Modifier import com.varabyte.kobweb.compose.ui.toAttrs @@ -19,7 +19,7 @@ actual class NavigationIconScope(val mdcTopAppBarSectionScope: MDCTopAppBarSecti mdcTopAppBarSectionScope.NavButton(attrs = { mdcIcon() contentDescription(contentDescription) - }) { Text(icon.mdcIcon.type) } + }) { Text(icon.name) } } actual class TopAppBarActionsScope(val mdcTopAppBarSectionScope: MDCTopAppBarSectionScope) { @@ -32,7 +32,7 @@ actual class TopAppBarActionsScope(val mdcTopAppBarSectionScope: MDCTopAppBarSec mdcTopAppBarSectionScope.ActionButton(attrs = { mdcIcon() contentDescription(contentDescription) - }) { Text(icon.mdcIcon.type) } + }) { Text(icon.name) } } @Composable diff --git a/compose-multiplatform-material/src/jsMain/kotlin/com/huanshankeji/compose/material/icons/Icons.js.kt b/compose-multiplatform-material/src/jsMain/kotlin/com/huanshankeji/compose/material/icons/Icons.js.kt deleted file mode 100644 index 35c026f5..00000000 --- a/compose-multiplatform-material/src/jsMain/kotlin/com/huanshankeji/compose/material/icons/Icons.js.kt +++ /dev/null @@ -1,5 +0,0 @@ -package com.huanshankeji.compose.material.icons - -import dev.petuska.kmdcx.icons.MDCIcon - -actual class Icon(val mdcIcon: MDCIcon) diff --git a/compose-multiplatform-material/src/jsMain/kotlin/com/huanshankeji/compose/material/icons/IconsMdc.kt b/compose-multiplatform-material/src/jsMain/kotlin/com/huanshankeji/compose/material/icons/IconsMdc.kt new file mode 100644 index 00000000..6d11198c --- /dev/null +++ b/compose-multiplatform-material/src/jsMain/kotlin/com/huanshankeji/compose/material/icons/IconsMdc.kt @@ -0,0 +1,8 @@ +package com.huanshankeji.compose.material.icons + +import dev.petuska.kmdcx.icons.MDCIcon + +val mdcIconMap = MDCIcon.entries.associateBy { it.type } + +fun Icon.toMDCIcon() = + mdcIconMap.getValue(name) diff --git a/compose-multiplatform-material/src/jsMain/kotlin/com/huanshankeji/compose/material/icons/filled/Icons.js.kt b/compose-multiplatform-material/src/jsMain/kotlin/com/huanshankeji/compose/material/icons/filled/Icons.js.kt deleted file mode 100644 index dfb95d7b..00000000 --- a/compose-multiplatform-material/src/jsMain/kotlin/com/huanshankeji/compose/material/icons/filled/Icons.js.kt +++ /dev/null @@ -1,9 +0,0 @@ -package com.huanshankeji.compose.material.icons.filled - -import com.huanshankeji.compose.material.icons.Icon -import com.huanshankeji.compose.material.icons.Icons -import dev.petuska.kmdcx.icons.MDCIcon - -actual val Icons.Filled.Add: Icon get() = Icon(MDCIcon.Add) -actual val Icons.Filled.Menu: Icon get() = Icon(MDCIcon.Menu) -actual val Icons.Filled.Search: Icon get() = Icon(MDCIcon.Search) diff --git a/compose-multiplatform-material3/build.gradle.kts b/compose-multiplatform-material3/build.gradle.kts index 0c8015ab..9ae453fa 100644 --- a/compose-multiplatform-material3/build.gradle.kts +++ b/compose-multiplatform-material3/build.gradle.kts @@ -16,6 +16,7 @@ kotlin { dependencies { api(compose.runtime) api(project(":compose-multiplatform-common")) + api(project(":compose-multiplatform-material-icons-core")) //compileOnly(compose.material) // for KDoc element links only } } diff --git a/compose-multiplatform-material3/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material3/Icon.androidxCommon.kt b/compose-multiplatform-material3/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material3/Icon.androidxCommon.kt new file mode 100644 index 00000000..74372315 --- /dev/null +++ b/compose-multiplatform-material3/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material3/Icon.androidxCommon.kt @@ -0,0 +1,13 @@ +package com.huanshankeji.compose.material3 + +import androidx.compose.runtime.Composable +import com.huanshankeji.compose.material.icons.Icon +import com.huanshankeji.compose.ui.Modifier + +@Composable +actual fun Icon( + icon: Icon, + contentDescription: String?, + modifier: Modifier +) = + androidx.compose.material3.Icon(icon, contentDescription, modifier.platformModifier) diff --git a/compose-multiplatform-material3/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material3/ext/TextField.androidxCommon.kt b/compose-multiplatform-material3/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material3/ext/TextField.androidxCommon.kt index 8518a670..e16f0e44 100644 --- a/compose-multiplatform-material3/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material3/ext/TextField.androidxCommon.kt +++ b/compose-multiplatform-material3/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material3/ext/TextField.androidxCommon.kt @@ -5,12 +5,21 @@ import androidx.compose.runtime.Composable import com.huanshankeji.compose.foundation.text.KeyboardActions import com.huanshankeji.compose.foundation.text.KeyboardOptions import com.huanshankeji.compose.foundation.text.toPlatformValue +import com.huanshankeji.compose.material.icons.Icon +import com.huanshankeji.compose.material3.Icon import com.huanshankeji.compose.ui.Modifier // This function can be moved into a common file. fun String?.ToNullableTextComposable(): (@Composable () -> Unit)? = this?.let { { Text(it) } } +private fun (@Composable ((Modifier) -> Unit)?).toContentWithoutModifier(): @Composable (() -> Unit)? = + this?.let { { it(Modifier) } } + +private fun Icon?.toIconContent(): @Composable (() -> Unit)? = + this?.let { { Icon(it, null) } } + + @Composable actual fun TextField( value: String, @@ -52,6 +61,88 @@ actual fun TextField( minLines = lines ) +@Composable +actual fun TextFieldWithModifierPassedToIcon( + value: String, + onValueChange: (String) -> Unit, + modifier: Modifier, + enabled: Boolean, + readOnly: Boolean, + label: String?, + placeholder: String?, + leadingIcon: @Composable ((Modifier) -> Unit)?, + trailingIcon: @Composable ((Modifier) -> Unit)?, + prefix: String?, + suffix: String?, + supportingText: String?, + isError: Boolean, + keyboardOptions: KeyboardOptions, + keyboardActions: KeyboardActions, + singleLine: Boolean, + lines: Int +) = + TextField( + value, + onValueChange, + modifier, + enabled, + readOnly, + label, + placeholder, + leadingIcon.toContentWithoutModifier(), + trailingIcon.toContentWithoutModifier(), + prefix, + suffix, + supportingText, + isError, + keyboardOptions, + keyboardActions, + singleLine, + lines + ) + + +@Composable +actual fun TextFieldWithMaterialIcons( + value: String, + onValueChange: (String) -> Unit, + modifier: Modifier, + enabled: Boolean, + readOnly: Boolean, + label: String?, + placeholder: String?, + leadingIcon: Icon?, + trailingIcon: Icon?, + prefix: String?, + suffix: String?, + supportingText: String?, + isError: Boolean, + keyboardOptions: KeyboardOptions, + keyboardActions: KeyboardActions, + singleLine: Boolean, + lines: Int +) = + TextField( + value, + onValueChange, + modifier, + enabled, + readOnly, + label, + placeholder, + leadingIcon.toIconContent(), + trailingIcon.toIconContent(), + prefix, + suffix, + supportingText, + isError, + keyboardOptions, + keyboardActions, + singleLine, + lines + ) + + @Composable actual fun OutlinedTextField( value: String, @@ -92,3 +183,83 @@ actual fun OutlinedTextField( maxLines = lines, minLines = lines ) + +@Composable +actual fun OutlinedTextFieldWithModifierPassedToIcon( + value: String, + onValueChange: (String) -> Unit, + modifier: Modifier, + enabled: Boolean, + readOnly: Boolean, + label: String?, + placeholder: String?, + leadingIcon: @Composable ((Modifier) -> Unit)?, + trailingIcon: @Composable ((Modifier) -> Unit)?, + prefix: String?, + suffix: String?, + supportingText: String?, + isError: Boolean, + keyboardOptions: KeyboardOptions, + keyboardActions: KeyboardActions, + singleLine: Boolean, + lines: Int +) = + OutlinedTextField( + value, + onValueChange, + modifier, + enabled, + readOnly, + label, + placeholder, + leadingIcon.toContentWithoutModifier(), + trailingIcon.toContentWithoutModifier(), + prefix, + suffix, + supportingText, + isError, + keyboardOptions, + keyboardActions, + singleLine, + lines + ) + +@Composable +actual fun OutlinedTextFieldWithMaterialIcons( + value: String, + onValueChange: (String) -> Unit, + modifier: Modifier, + enabled: Boolean, + readOnly: Boolean, + label: String?, + placeholder: String?, + leadingIcon: Icon?, + trailingIcon: Icon?, + prefix: String?, + suffix: String?, + supportingText: String?, + isError: Boolean, + keyboardOptions: KeyboardOptions, + keyboardActions: KeyboardActions, + singleLine: Boolean, + lines: Int +) = + OutlinedTextField( + value, + onValueChange, + modifier, + enabled, + readOnly, + label, + placeholder, + leadingIcon.toIconContent(), + trailingIcon.toIconContent(), + prefix, + suffix, + supportingText, + isError, + keyboardOptions, + keyboardActions, + singleLine, + lines + ) diff --git a/compose-multiplatform-material3/src/commonMain/kotlin/com/huanshankeji/compose/material3/Icon.kt b/compose-multiplatform-material3/src/commonMain/kotlin/com/huanshankeji/compose/material3/Icon.kt new file mode 100644 index 00000000..ab926734 --- /dev/null +++ b/compose-multiplatform-material3/src/commonMain/kotlin/com/huanshankeji/compose/material3/Icon.kt @@ -0,0 +1,13 @@ +package com.huanshankeji.compose.material3 + +import androidx.compose.runtime.Composable +import com.huanshankeji.compose.material.icons.Icon +import com.huanshankeji.compose.ui.Modifier + +@Composable +expect fun Icon( + icon: Icon, + contentDescription: String?, + modifier: Modifier = Modifier + //tint: Color = LocalContentColor.current +) diff --git a/compose-multiplatform-material3/src/commonMain/kotlin/com/huanshankeji/compose/material3/ext/TextField.kt b/compose-multiplatform-material3/src/commonMain/kotlin/com/huanshankeji/compose/material3/ext/TextField.kt index 28eed6a7..a3f8bae5 100644 --- a/compose-multiplatform-material3/src/commonMain/kotlin/com/huanshankeji/compose/material3/ext/TextField.kt +++ b/compose-multiplatform-material3/src/commonMain/kotlin/com/huanshankeji/compose/material3/ext/TextField.kt @@ -3,6 +3,7 @@ package com.huanshankeji.compose.material3.ext import androidx.compose.runtime.Composable import com.huanshankeji.compose.foundation.text.KeyboardActions import com.huanshankeji.compose.foundation.text.KeyboardOptions +import com.huanshankeji.compose.material.icons.Icon import com.huanshankeji.compose.ui.Modifier @Composable @@ -31,6 +32,53 @@ expect fun TextField( // pattern: String? // This can be supported with Kotlin's `Regex` so it's not supported here. ) +/** + * @param leadingIcon the [Modifier] parameter contains the attributes to be set on this icon on JS. + * @param trailingIcon ditto. + */ +@Composable +expect fun TextFieldWithModifierPassedToIcon( + value: String, + onValueChange: (String) -> Unit, + modifier: Modifier = Modifier, + enabled: Boolean = true, + readOnly: Boolean = false, + label: String? = null, + placeholder: String? = null, + leadingIcon: @Composable ((Modifier) -> Unit)? = null, + trailingIcon: @Composable ((Modifier) -> Unit)? = null, + prefix: String? = null, + suffix: String? = null, + supportingText: String? = null, + isError: Boolean = false, + keyboardOptions: KeyboardOptions = KeyboardOptions.Default, + keyboardActions: KeyboardActions = KeyboardActions.Default, + singleLine: Boolean = false, + lines: Int = 1 +) + +@Composable +expect fun TextFieldWithMaterialIcons( + value: String, + onValueChange: (String) -> Unit, + modifier: Modifier = Modifier, + enabled: Boolean = true, + readOnly: Boolean = false, + label: String? = null, + placeholder: String? = null, + leadingIcon: Icon? = null, + trailingIcon: Icon? = null, + prefix: String? = null, + suffix: String? = null, + supportingText: String? = null, + isError: Boolean = false, + keyboardOptions: KeyboardOptions = KeyboardOptions.Default, + keyboardActions: KeyboardActions = KeyboardActions.Default, + singleLine: Boolean = false, + lines: Int = 1 +) + + @Composable expect fun OutlinedTextField( value: String, @@ -51,3 +99,49 @@ expect fun OutlinedTextField( singleLine: Boolean = false, lines: Int = 1 ) + +/** + * @param leadingIcon the [Modifier] parameter contains the attributes to be set on this icon on JS. + * @param trailingIcon ditto. + */ +@Composable +expect fun OutlinedTextFieldWithModifierPassedToIcon( + value: String, + onValueChange: (String) -> Unit, + modifier: Modifier = Modifier, + enabled: Boolean = true, + readOnly: Boolean = false, + label: String? = null, + placeholder: String? = null, + leadingIcon: @Composable ((Modifier) -> Unit)? = null, + trailingIcon: @Composable ((Modifier) -> Unit)? = null, + prefix: String? = null, + suffix: String? = null, + supportingText: String? = null, + isError: Boolean = false, + keyboardOptions: KeyboardOptions = KeyboardOptions.Default, + keyboardActions: KeyboardActions = KeyboardActions.Default, + singleLine: Boolean = false, + lines: Int = 1 +) + +@Composable +expect fun OutlinedTextFieldWithMaterialIcons( + value: String, + onValueChange: (String) -> Unit, + modifier: Modifier = Modifier, + enabled: Boolean = true, + readOnly: Boolean = false, + label: String? = null, + placeholder: String? = null, + leadingIcon: Icon? = null, + trailingIcon: Icon? = null, + prefix: String? = null, + suffix: String? = null, + supportingText: String? = null, + isError: Boolean = false, + keyboardOptions: KeyboardOptions = KeyboardOptions.Default, + keyboardActions: KeyboardActions = KeyboardActions.Default, + singleLine: Boolean = false, + lines: Int = 1 +) diff --git a/compose-multiplatform-material3/src/jsMain/kotlin/com/huanshankeji/compose/material3/Icon.js.kt b/compose-multiplatform-material3/src/jsMain/kotlin/com/huanshankeji/compose/material3/Icon.js.kt new file mode 100644 index 00000000..34de0b29 --- /dev/null +++ b/compose-multiplatform-material3/src/jsMain/kotlin/com/huanshankeji/compose/material3/Icon.js.kt @@ -0,0 +1,18 @@ +package com.huanshankeji.compose.material3 + +import androidx.compose.runtime.Composable +import com.huanshankeji.compose.contentDescription +import com.huanshankeji.compose.html.material3.MdIcon +import com.huanshankeji.compose.material.icons.Icon +import com.huanshankeji.compose.ui.Modifier +import com.varabyte.kobweb.compose.ui.toAttrs + +@Composable +actual fun Icon( + icon: Icon, + contentDescription: String?, + modifier: Modifier +) = + MdIcon(attrs = modifier.platformModifier.toAttrs { + contentDescription(contentDescription) + }, materialIconName = icon.name) diff --git a/compose-multiplatform-material3/src/jsMain/kotlin/com/huanshankeji/compose/material3/ext/TextField.js.kt b/compose-multiplatform-material3/src/jsMain/kotlin/com/huanshankeji/compose/material3/ext/TextField.js.kt index a927e184..435220ec 100644 --- a/compose-multiplatform-material3/src/jsMain/kotlin/com/huanshankeji/compose/material3/ext/TextField.js.kt +++ b/compose-multiplatform-material3/src/jsMain/kotlin/com/huanshankeji/compose/material3/ext/TextField.js.kt @@ -1,13 +1,17 @@ package com.huanshankeji.compose.material3.ext import androidx.compose.runtime.Composable +import com.huanshankeji.compose.foundation.layout.Box import com.huanshankeji.compose.foundation.text.KeyboardActions import com.huanshankeji.compose.foundation.text.KeyboardOptions import com.huanshankeji.compose.foundation.text.attrsFrom import com.huanshankeji.compose.html.material3.MdFilledTextField import com.huanshankeji.compose.html.material3.MdOutlinedTextField import com.huanshankeji.compose.html.material3.MdTextFieldScope +import com.huanshankeji.compose.material.icons.Icon +import com.huanshankeji.compose.material3.Icon import com.huanshankeji.compose.ui.Modifier +import com.huanshankeji.compose.ui.toCommonModifier import com.huanshankeji.compose.web.attributes.ext.onInput import com.huanshankeji.compose.web.attributes.isFalseOrNull import com.huanshankeji.compose.web.attributes.isTrueOrNull @@ -29,13 +33,21 @@ private fun Modifier.toTextFieldAttrs( attrsFrom(keyboardOptions, keyboardActions) } -private fun TextFieldContent(): @Composable MdTextFieldScope.() -> Unit = { - // leadingIcon?.invoke() // TODO - PlatformModifier.attrsModifier { slot(MdTextFieldScope.Slot.LeadingIcon) } - // trailingIcon?.invoke() // TODO - PlatformModifier.attrsModifier { slot(MdTextFieldScope.Slot.TrailingIcon) } +private fun TextFieldContent( + leadingIcon: @Composable ((Modifier) -> Unit)?, + trailingIcon: @Composable ((Modifier) -> Unit)?, +): @Composable MdTextFieldScope.() -> Unit = { + leadingIcon?.invoke(PlatformModifier.attrsModifier { slot(MdTextFieldScope.Slot.LeadingIcon) }.toCommonModifier()) + trailingIcon?.invoke(PlatformModifier.attrsModifier { slot(MdTextFieldScope.Slot.TrailingIcon) }.toCommonModifier()) } +private fun (@Composable (() -> Unit)?).toBoxedContentWithModifier(): @Composable ((Modifier) -> Unit)? = + this?.let { { modifier -> Box(modifier) { it() } } } + +private fun Icon?.toIconContentWithModifier(): @Composable ((Modifier) -> Unit)? = + this?.let { { modifier -> Icon(it, null, modifier) } } + + @Composable actual fun TextField( value: String, @@ -55,6 +67,46 @@ actual fun TextField( keyboardActions: KeyboardActions, singleLine: Boolean, lines: Int +) = + TextFieldWithModifierPassedToIcon( + value, + onValueChange, + modifier, + enabled, + readOnly, + label, + placeholder, + leadingIcon.toBoxedContentWithModifier(), + trailingIcon.toBoxedContentWithModifier(), + prefix, + suffix, + supportingText, + isError, + keyboardOptions, + keyboardActions, + singleLine, + lines + ) + +@Composable +actual fun TextFieldWithModifierPassedToIcon( + value: String, + onValueChange: (String) -> Unit, + modifier: Modifier, + enabled: Boolean, + readOnly: Boolean, + label: String?, + placeholder: String?, + leadingIcon: @Composable ((Modifier) -> Unit)?, + trailingIcon: @Composable ((Modifier) -> Unit)?, + prefix: String?, + suffix: String?, + supportingText: String?, + isError: Boolean, + keyboardOptions: KeyboardOptions, + keyboardActions: KeyboardActions, + singleLine: Boolean, + lines: Int ) = MdFilledTextField( enabled.isFalseOrNull(), @@ -72,7 +124,47 @@ actual fun TextField( readOnly = readOnly.isTrueOrNull(), attrs = modifier.toTextFieldAttrs(onValueChange, keyboardOptions, keyboardActions), - content = TextFieldContent() + content = TextFieldContent(leadingIcon, trailingIcon) + ) + +@Composable +actual fun TextFieldWithMaterialIcons( + value: String, + onValueChange: (String) -> Unit, + modifier: Modifier, + enabled: Boolean, + readOnly: Boolean, + label: String?, + placeholder: String?, + leadingIcon: Icon?, + trailingIcon: Icon?, + prefix: String?, + suffix: String?, + supportingText: String?, + isError: Boolean, + keyboardOptions: KeyboardOptions, + keyboardActions: KeyboardActions, + singleLine: Boolean, + lines: Int +) = + TextFieldWithModifierPassedToIcon( + value, + onValueChange, + modifier, + enabled, + readOnly, + label, + placeholder, + leadingIcon.toIconContentWithModifier(), + trailingIcon.toIconContentWithModifier(), + prefix, + suffix, + supportingText, + isError, + keyboardOptions, + keyboardActions, + singleLine, + lines ) @@ -95,6 +187,46 @@ actual fun OutlinedTextField( keyboardActions: KeyboardActions, singleLine: Boolean, lines: Int +) = + OutlinedTextFieldWithModifierPassedToIcon( + value, + onValueChange, + modifier, + enabled, + readOnly, + label, + placeholder, + leadingIcon.toBoxedContentWithModifier(), + trailingIcon.toBoxedContentWithModifier(), + prefix, + suffix, + supportingText, + isError, + keyboardOptions, + keyboardActions, + singleLine, + lines + ) + +@Composable +actual fun OutlinedTextFieldWithModifierPassedToIcon( + value: String, + onValueChange: (String) -> Unit, + modifier: Modifier, + enabled: Boolean, + readOnly: Boolean, + label: String?, + placeholder: String?, + leadingIcon: @Composable ((Modifier) -> Unit)?, + trailingIcon: @Composable ((Modifier) -> Unit)?, + prefix: String?, + suffix: String?, + supportingText: String?, + isError: Boolean, + keyboardOptions: KeyboardOptions, + keyboardActions: KeyboardActions, + singleLine: Boolean, + lines: Int ) = MdOutlinedTextField( enabled.isFalseOrNull(), @@ -112,5 +244,45 @@ actual fun OutlinedTextField( readOnly = readOnly.isTrueOrNull(), attrs = modifier.toTextFieldAttrs(onValueChange, keyboardOptions, keyboardActions), - content = TextFieldContent() + content = TextFieldContent(leadingIcon, trailingIcon) + ) + +@Composable +actual fun OutlinedTextFieldWithMaterialIcons( + value: String, + onValueChange: (String) -> Unit, + modifier: Modifier, + enabled: Boolean, + readOnly: Boolean, + label: String?, + placeholder: String?, + leadingIcon: Icon?, + trailingIcon: Icon?, + prefix: String?, + suffix: String?, + supportingText: String?, + isError: Boolean, + keyboardOptions: KeyboardOptions, + keyboardActions: KeyboardActions, + singleLine: Boolean, + lines: Int +) = + OutlinedTextFieldWithModifierPassedToIcon( + value, + onValueChange, + modifier, + enabled, + readOnly, + label, + placeholder, + leadingIcon.toIconContentWithModifier(), + trailingIcon.toIconContentWithModifier(), + prefix, + suffix, + supportingText, + isError, + keyboardOptions, + keyboardActions, + singleLine, + lines ) diff --git a/demo/src/commonMain/kotlin/com/huanshankeji/compose/material/demo/Material2.kt b/demo/src/commonMain/kotlin/com/huanshankeji/compose/material/demo/Material2.kt index 664291b7..52581b11 100644 --- a/demo/src/commonMain/kotlin/com/huanshankeji/compose/material/demo/Material2.kt +++ b/demo/src/commonMain/kotlin/com/huanshankeji/compose/material/demo/Material2.kt @@ -113,19 +113,19 @@ fun Material2() { } var text by remember { mutableStateOf("") } - TextField( + TextFieldWithMaterialIcons( text, { text = it }, label = "Demo text field", - leadingIcon = { Icon(Icons.Default.Add, null) }, - trailingIcon = { Icon(Icons.Default.Menu, null) }, + leadingIcon = Icons.Default.Add, + trailingIcon = Icons.Default.Menu, keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number), singleLine = true ) - OutlinedTextField( + OutlinedTextFieldWithMaterialIcons( text, { text = it }, label = "Demo text field", - leadingIcon = { Icon(Icons.Default.Add, null) }, - trailingIcon = { Icon(Icons.Default.Menu, null) }, + leadingIcon = Icons.Default.Add, + trailingIcon = Icons.Default.Menu, keyboardOptions = KeyboardOptions( KeyboardCapitalization.Words, true, imeAction = ImeAction.Search ), diff --git a/demo/src/commonMain/kotlin/com/huanshankeji/compose/material/demo/Material3.kt b/demo/src/commonMain/kotlin/com/huanshankeji/compose/material/demo/Material3.kt index a6f9316b..0a79df39 100644 --- a/demo/src/commonMain/kotlin/com/huanshankeji/compose/material/demo/Material3.kt +++ b/demo/src/commonMain/kotlin/com/huanshankeji/compose/material/demo/Material3.kt @@ -10,6 +10,9 @@ import com.huanshankeji.compose.foundation.text.ext.InlineBasicText import com.huanshankeji.compose.foundation.text.input.ImeAction import com.huanshankeji.compose.foundation.text.input.KeyboardCapitalization import com.huanshankeji.compose.foundation.text.input.KeyboardType +import com.huanshankeji.compose.material.icons.Icons +import com.huanshankeji.compose.material.icons.filled.Add +import com.huanshankeji.compose.material.icons.filled.Menu import com.huanshankeji.compose.material3.Checkbox import com.huanshankeji.compose.material3.Switch import com.huanshankeji.compose.material3.ext.* @@ -46,21 +49,25 @@ fun Material3() { val prefix = "prefix" val suffix = "suffix" val supportingText = "supporting text" - TextField( + TextFieldWithMaterialIcons( text, { text = it }, label = label, placeholder = placeholder, + leadingIcon = Icons.Default.Add, + trailingIcon = Icons.Default.Menu, prefix = prefix, suffix = suffix, supportingText = supportingText, keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number) ) - OutlinedTextField( + OutlinedTextFieldWithMaterialIcons( text, { text = it }, label = label, placeholder = placeholder, + leadingIcon = Icons.Default.Add, + trailingIcon = Icons.Default.Menu, prefix = prefix, suffix = suffix, supportingText = supportingText, diff --git a/demo/src/jsMain/resources/index.html b/demo/src/jsMain/resources/index.html index 1913ade4..f876b1f8 100644 --- a/demo/src/jsMain/resources/index.html +++ b/demo/src/jsMain/resources/index.html @@ -10,6 +10,8 @@ margin: 0; } + + diff --git a/settings.gradle.kts b/settings.gradle.kts index c5f51294..1e003326 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -3,6 +3,7 @@ rootProject.name = "compose-multiplatform-material" include("compose-multiplatform-common") // TODO consider splitting into several modules including `foundation`, `ui`, etc. include("compose-multiplatform-common:legacy") project(":compose-multiplatform-common:legacy").name = "compose-multiplatform-common-legacy" +include("compose-multiplatform-material-icons-core") include("compose-multiplatform-material") include("compose-multiplatform-material3") include("demo") From eddea8701f5bb2597cd28747b6201a7d9b0d545b Mon Sep 17 00:00:00 2001 From: Shreck Ye Date: Fri, 3 May 2024 00:32:49 +0800 Subject: [PATCH 50/75] Self-host Material Symbols for the Material Icons required by the Material 3 module in the demo The corresponding commit: https://github.com/huanshankeji/compose-html-material/commit/b36f57e3b99db7135f9f9463b81b4457c0f11a11 --- README.md | 4 ++++ demo/build.gradle.kts | 1 + .../kotlin/com/huanshankeji/compose/material/demo/Main.kt | 2 ++ demo/src/jsMain/resources/index.html | 2 -- kotlin-js-store/yarn.lock | 5 +++++ 5 files changed, 12 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index a39feb7d..ade5c67d 100644 --- a/README.md +++ b/README.md @@ -106,6 +106,10 @@ repositories { } ``` +### Material Symbols & Icons on JS + +See [the corresponding section in Compose HTML Material]() for Material Icons on JS. + ## About Kobweb Silk The Kotlin/JS (Compose HTML) portion of this project depends on [Kobweb Compose](https://github.com/varabyte/kobweb/blob/main/frontend/kobweb-compose/README.md) of [Kobweb Silk](https://github.com/varabyte/kobweb?tab=readme-ov-file#silk) which is a UI layer built upon Compose HTML that provides `Modifier` (type-safe CSS API wrappers) and layout APIs. Here is a list of topics in their README.md that should be helpful when you use this library in Compose HTML, especially if you need to customize the components further on Kotlin/JS (Compose HTML): diff --git a/demo/build.gradle.kts b/demo/build.gradle.kts index bf9c1121..9cde3d94 100644 --- a/demo/build.gradle.kts +++ b/demo/build.gradle.kts @@ -77,6 +77,7 @@ kotlin { jsMain { dependencies { implementation(compose.html.core) + implementation(npm("material-symbols", "0.17.4")) } } } diff --git a/demo/src/jsMain/kotlin/com/huanshankeji/compose/material/demo/Main.kt b/demo/src/jsMain/kotlin/com/huanshankeji/compose/material/demo/Main.kt index a80eff37..8766b2c7 100644 --- a/demo/src/jsMain/kotlin/com/huanshankeji/compose/material/demo/Main.kt +++ b/demo/src/jsMain/kotlin/com/huanshankeji/compose/material/demo/Main.kt @@ -1,7 +1,9 @@ package com.huanshankeji.compose.material.demo +import com.huanshankeji.compose.html.material3.require import org.jetbrains.compose.web.renderComposableInBody fun main() { + require("material-symbols/outlined.css") renderComposableInBody { App() } } diff --git a/demo/src/jsMain/resources/index.html b/demo/src/jsMain/resources/index.html index f876b1f8..1913ade4 100644 --- a/demo/src/jsMain/resources/index.html +++ b/demo/src/jsMain/resources/index.html @@ -10,8 +10,6 @@ margin: 0; } - - diff --git a/kotlin-js-store/yarn.lock b/kotlin-js-store/yarn.lock index c81a6b19..56c58375 100644 --- a/kotlin-js-store/yarn.lock +++ b/kotlin-js-store/yarn.lock @@ -2418,6 +2418,11 @@ material-icons@^1.13.12: resolved "https://registry.yarnpkg.com/material-icons/-/material-icons-1.13.12.tgz#eed4082bf0426642edeb027e75397e3064adc536" integrity sha512-/2YoaB79IjUK2B2JB+vIXXYGtBfHb/XG66LvoKVM5ykHW7yfrV5SP6d7KLX6iijY6/G9GqwgtPQ/sbhFnOURVA== +material-symbols@0.17.4: + version "0.17.4" + resolved "https://registry.yarnpkg.com/material-symbols/-/material-symbols-0.17.4.tgz#d44f9c47860487e74b2e9735425d49d99933ec01" + integrity sha512-5zI+rSzAidMJxAIrQCVwnp4rMjFnx8aQg68lfFXtaDeksZzJ7m8eDl16y9bRNxMosuYbLKeDHDbOWHPJJTSLhQ== + media-typer@0.3.0: version "0.3.0" resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748" From 929d13125dfc7159f898fdeca72004acfa48d2c1 Mon Sep 17 00:00:00 2001 From: Shreck Ye Date: Fri, 3 May 2024 22:27:38 +0800 Subject: [PATCH 51/75] Refactor `Button` in the `ext` package to take icon parameters and get rid of `ButtonScope` --- .../material3/ext/Button.androidxCommon.kt | 47 +++++++++++++++++-- .../compose/material3/ext/Button.kt | 32 +++++++++++-- .../compose/material3/ext/TextField.kt | 11 ++++- .../compose/material3/Button.js.kt | 6 ++- .../compose/material3/ext/Button.js.kt | 12 ++++- .../compose/material/demo/Material3.kt | 4 +- 6 files changed, 98 insertions(+), 14 deletions(-) diff --git a/compose-multiplatform-material3/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material3/ext/Button.androidxCommon.kt b/compose-multiplatform-material3/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material3/ext/Button.androidxCommon.kt index 4317d543..6b75e36b 100644 --- a/compose-multiplatform-material3/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material3/ext/Button.androidxCommon.kt +++ b/compose-multiplatform-material3/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material3/ext/Button.androidxCommon.kt @@ -1,24 +1,61 @@ package com.huanshankeji.compose.material3.ext import androidx.compose.foundation.layout.RowScope +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.size import androidx.compose.runtime.Composable +import androidx.compose.ui.unit.dp +import com.huanshankeji.compose.layout.size import com.huanshankeji.compose.ui.Modifier +// TODO remove @Composable private fun (@Composable (ButtonScope.() -> Unit)).toButtonScopeContent(): @Composable RowScope.() -> Unit = { ButtonScope.(this@toButtonScopeContent)() } +@Composable +private fun (@Composable (() -> Unit)).toRowScopeContent( + icon: @Composable ((Modifier) -> Unit)?, + isTrailingIcon: Boolean +): @Composable RowScope.() -> Unit = + { + // see https://m3.material.io/components/buttons/specs#34dda7d9-40df-48ce-a169-1eaffe2e1835 and https://m3.material.io/components/buttons/specs#309d928e-e9ef-41dd-89fc-9bc51f78709c + + @Composable + fun Spacer() = + Spacer(androidx.compose.ui.Modifier.size(8.dp)) + + if (icon === null) + this@toRowScopeContent() + else { + @Composable + fun icon() = + icon(Modifier.size(18.dp)) + + if (isTrailingIcon) { + this@toRowScopeContent() + Spacer() + icon() + } else { + icon() + Spacer() + this@toRowScopeContent() + } + } + } + @Composable actual fun Button( onClick: () -> Unit, modifier: Modifier, enabled: Boolean, - content: @Composable ButtonScope.() -> Unit -) = - androidx.compose.material3.Button( - onClick, modifier.platformModifier, enabled, content = content.toButtonScopeContent() - ) + icon: @Composable ((Modifier) -> Unit)?, + isTrailingIcon: Boolean, + content: @Composable () -> Unit +) = androidx.compose.material3.Button( + onClick, modifier.platformModifier, enabled, content = content.toRowScopeContent(icon, isTrailingIcon) +) @Composable actual fun ElevatedButton( diff --git a/compose-multiplatform-material3/src/commonMain/kotlin/com/huanshankeji/compose/material3/ext/Button.kt b/compose-multiplatform-material3/src/commonMain/kotlin/com/huanshankeji/compose/material3/ext/Button.kt index c7c85fdc..8d11bc6b 100644 --- a/compose-multiplatform-material3/src/commonMain/kotlin/com/huanshankeji/compose/material3/ext/Button.kt +++ b/compose-multiplatform-material3/src/commonMain/kotlin/com/huanshankeji/compose/material3/ext/Button.kt @@ -1,19 +1,42 @@ package com.huanshankeji.compose.material3.ext import androidx.compose.runtime.Composable +import com.huanshankeji.compose.material.icons.Icon +import com.huanshankeji.compose.material3.Icon import com.huanshankeji.compose.ui.Modifier /** * filled button + * @param icon the [Modifier] parameter contains the attributes to be set on this icon on JS. You are supposed to pass this [Modifier] to the top-level composable that you invoke inside. */ @Composable expect fun Button( onClick: () -> Unit, modifier: Modifier = Modifier, enabled: Boolean = true, - content: @Composable ButtonScope.() -> Unit + icon: @Composable ((Modifier) -> Unit)? = null, + isTrailingIcon: Boolean = false, + content: @Composable () -> Unit ) +@Composable +fun ButtonWithMaterialIcon( + onClick: () -> Unit, + modifier: Modifier = Modifier, + enabled: Boolean = true, + icon: Icon?, + isTrailingIcon: Boolean = false, + content: @Composable () -> Unit +) = + Button( + onClick, + modifier, + enabled, + icon?.let { { modifier -> Icon(it, null, modifier) } }, + isTrailingIcon, + content + ) + /** * a shortcut to `Button` */ @@ -22,9 +45,11 @@ fun FilledButton( onClick: () -> Unit, modifier: Modifier = Modifier, enabled: Boolean = true, - content: @Composable ButtonScope.() -> Unit + icon: @Composable ((Modifier) -> Unit)? = null, + isTrailingIcon: Boolean = false, + content: @Composable () -> Unit ) = - Button(onClick, modifier, enabled, content) + Button(onClick, modifier, enabled, icon, isTrailingIcon, content) @Composable expect fun ElevatedButton( @@ -58,6 +83,7 @@ expect fun TextButton( content: @Composable ButtonScope.() -> Unit ) +// TODO remove expect class ButtonScope { @Composable fun Icon(/* TODO */) diff --git a/compose-multiplatform-material3/src/commonMain/kotlin/com/huanshankeji/compose/material3/ext/TextField.kt b/compose-multiplatform-material3/src/commonMain/kotlin/com/huanshankeji/compose/material3/ext/TextField.kt index a3f8bae5..eaa0749d 100644 --- a/compose-multiplatform-material3/src/commonMain/kotlin/com/huanshankeji/compose/material3/ext/TextField.kt +++ b/compose-multiplatform-material3/src/commonMain/kotlin/com/huanshankeji/compose/material3/ext/TextField.kt @@ -6,6 +6,13 @@ import com.huanshankeji.compose.foundation.text.KeyboardOptions import com.huanshankeji.compose.material.icons.Icon import com.huanshankeji.compose.ui.Modifier +/* +TODO Remove this to avoid confusion caused by too many similar functions, and rename the following `TextFieldWithModifierPassedToIcon` to `TextField`. + Do the same to the similar `OutlinedTextField`. + This function was added in order to be more akin to the `androidx.compose.material3` one, but it seems unnecessary now on second thought. + The user should be recommended to pass the `Modifier` for the component to work better on JS. + The newly-refactored `ext` button composables are designed in this way. + */ @Composable expect fun TextField( value: String, @@ -33,7 +40,7 @@ expect fun TextField( ) /** - * @param leadingIcon the [Modifier] parameter contains the attributes to be set on this icon on JS. + * @param leadingIcon the [Modifier] parameter contains the attributes to be set on this icon on JS. You are supposed to pass this [Modifier] to the top-level composable that you invoke inside. * @param trailingIcon ditto. */ @Composable @@ -101,7 +108,7 @@ expect fun OutlinedTextField( ) /** - * @param leadingIcon the [Modifier] parameter contains the attributes to be set on this icon on JS. + * @param leadingIcon the [Modifier] parameter contains the attributes to be set on this icon on JS. You are supposed to pass this [Modifier] to the top-level composable that you invoke inside. * @param trailingIcon ditto. */ @Composable diff --git a/compose-multiplatform-material3/src/jsMain/kotlin/com/huanshankeji/compose/material3/Button.js.kt b/compose-multiplatform-material3/src/jsMain/kotlin/com/huanshankeji/compose/material3/Button.js.kt index b3de33f9..68fc434e 100644 --- a/compose-multiplatform-material3/src/jsMain/kotlin/com/huanshankeji/compose/material3/Button.js.kt +++ b/compose-multiplatform-material3/src/jsMain/kotlin/com/huanshankeji/compose/material3/Button.js.kt @@ -7,6 +7,7 @@ import com.huanshankeji.compose.html.material3.* import com.huanshankeji.compose.ui.Modifier import com.huanshankeji.compose.web.attributes.Attrs import com.huanshankeji.compose.web.attributes.isFalseOrNull +import com.huanshankeji.compose.web.attributes.isTrueOrNull import com.varabyte.kobweb.compose.ui.toAttrs import org.w3c.dom.HTMLElement @@ -17,6 +18,7 @@ private fun Modifier.toButtonAttrs(onClick: () -> Unit): Attrs = @Composable private fun (@Composable (RowScope.() -> Unit)).toMdButtonScopeContent(): @Composable MdButtonScope.() -> Unit = + // TODO consider adding the row styles/classes to the button and remove the wrapping `Row` { Row(content = this@toMdButtonScopeContent) } @@ -25,10 +27,12 @@ internal fun CommonButton( onClick: () -> Unit, modifier: Modifier, enabled: Boolean, + isTrailingIcon: Boolean = false, content: @Composable MdButtonScope.() -> Unit ) = MdFilledButton( disabled = enabled.isFalseOrNull(), + trailingIcon = isTrailingIcon.isTrueOrNull(), attrs = modifier.toButtonAttrs(onClick), content = content ) @@ -40,7 +44,7 @@ actual fun Button( enabled: Boolean, content: @Composable RowScope.() -> Unit ) = - CommonButton(onClick, modifier, enabled, content.toMdButtonScopeContent()) + CommonButton(onClick, modifier, enabled, content = content.toMdButtonScopeContent()) @Composable internal fun CommonElevatedButton( diff --git a/compose-multiplatform-material3/src/jsMain/kotlin/com/huanshankeji/compose/material3/ext/Button.js.kt b/compose-multiplatform-material3/src/jsMain/kotlin/com/huanshankeji/compose/material3/ext/Button.js.kt index b390c692..b4755694 100644 --- a/compose-multiplatform-material3/src/jsMain/kotlin/com/huanshankeji/compose/material3/ext/Button.js.kt +++ b/compose-multiplatform-material3/src/jsMain/kotlin/com/huanshankeji/compose/material3/ext/Button.js.kt @@ -4,6 +4,9 @@ import androidx.compose.runtime.Composable import com.huanshankeji.compose.html.material3.MdButtonScope import com.huanshankeji.compose.material3.* import com.huanshankeji.compose.ui.Modifier +import com.huanshankeji.compose.ui.toCommonModifier +import com.varabyte.kobweb.compose.ui.attrsModifier +import com.varabyte.kobweb.compose.ui.Modifier as PlatformModifier @Composable private fun (@Composable (ButtonScope.() -> Unit)).toMdButtonScopeContent(): @Composable MdButtonScope.() -> Unit = @@ -15,9 +18,14 @@ actual fun Button( onClick: () -> Unit, modifier: Modifier, enabled: Boolean, - content: @Composable ButtonScope.() -> Unit + icon: @Composable ((Modifier) -> Unit)?, + isTrailingIcon: Boolean, + content: @Composable () -> Unit ) = - CommonButton(onClick, modifier, enabled, content.toMdButtonScopeContent()) + CommonButton(onClick, modifier, enabled) { + content() + icon?.invoke(PlatformModifier.attrsModifier { slotEqIcon() }.toCommonModifier()) + } @Composable actual fun ElevatedButton( diff --git a/demo/src/commonMain/kotlin/com/huanshankeji/compose/material/demo/Material3.kt b/demo/src/commonMain/kotlin/com/huanshankeji/compose/material/demo/Material3.kt index 0a79df39..c07dcd24 100644 --- a/demo/src/commonMain/kotlin/com/huanshankeji/compose/material/demo/Material3.kt +++ b/demo/src/commonMain/kotlin/com/huanshankeji/compose/material/demo/Material3.kt @@ -30,11 +30,13 @@ fun Material3() { val buttonScopeButtonContent: @Composable ButtonScope.() -> Unit = { buttonContent() } Row { RowScopeButton(onClick, content = rowScopeButtonContent) - Button(onClick, content = buttonScopeButtonContent) + Button(onClick, content = buttonContent) ElevatedButton(onClick, content = buttonScopeButtonContent) FilledTonalButton(onClick, content = buttonScopeButtonContent) OutlinedButton(onClick, content = buttonScopeButtonContent) TextButton(onClick, content = buttonScopeButtonContent) + + ButtonWithMaterialIcon(onClick, icon = Icons.Default.Add, content = buttonContent) } Row { From d1716796ac9cfc7aa947d45db10e0d6fbf0d8abe Mon Sep 17 00:00:00 2001 From: Shreck Ye Date: Sat, 4 May 2024 00:12:25 +0800 Subject: [PATCH 52/75] Refactor the reset of the button composables in the `ext` package to take icon parameters and get rid of `ButtonScope`, and fix a bug introduced in the previous commit that the `isTrailingIcon` is not passed in `com.huanshankeji.compose.material3.ext.Button` See the previous commit. --- .../material3/ext/Button.androidxCommon.kt | 36 ++++---- .../compose/material3/ext/Button.kt | 92 +++++++++++++++++-- .../compose/material3/Button.js.kt | 16 +++- .../compose/material3/ext/Button.js.kt | 48 +++++----- .../compose/material/demo/Material3.kt | 10 +- 5 files changed, 142 insertions(+), 60 deletions(-) diff --git a/compose-multiplatform-material3/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material3/ext/Button.androidxCommon.kt b/compose-multiplatform-material3/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material3/ext/Button.androidxCommon.kt index 6b75e36b..3e86a435 100644 --- a/compose-multiplatform-material3/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material3/ext/Button.androidxCommon.kt +++ b/compose-multiplatform-material3/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material3/ext/Button.androidxCommon.kt @@ -8,11 +8,6 @@ import androidx.compose.ui.unit.dp import com.huanshankeji.compose.layout.size import com.huanshankeji.compose.ui.Modifier -// TODO remove -@Composable -private fun (@Composable (ButtonScope.() -> Unit)).toButtonScopeContent(): @Composable RowScope.() -> Unit = - { ButtonScope.(this@toButtonScopeContent)() } - @Composable private fun (@Composable (() -> Unit)).toRowScopeContent( icon: @Composable ((Modifier) -> Unit)?, @@ -62,9 +57,11 @@ actual fun ElevatedButton( onClick: () -> Unit, modifier: Modifier, enabled: Boolean, - content: @Composable ButtonScope.() -> Unit + icon: @Composable ((Modifier) -> Unit)?, + isTrailingIcon: Boolean, + content: @Composable () -> Unit ) = androidx.compose.material3.ElevatedButton( - onClick, modifier.platformModifier, enabled, content = content.toButtonScopeContent() + onClick, modifier.platformModifier, enabled, content = content.toRowScopeContent(icon, isTrailingIcon) ) @Composable @@ -72,10 +69,12 @@ actual fun FilledTonalButton( onClick: () -> Unit, modifier: Modifier, enabled: Boolean, - content: @Composable ButtonScope.() -> Unit + icon: @Composable ((Modifier) -> Unit)?, + isTrailingIcon: Boolean, + content: @Composable () -> Unit ) = androidx.compose.material3.FilledTonalButton( - onClick, modifier.platformModifier, enabled, content = content.toButtonScopeContent() + onClick, modifier.platformModifier, enabled, content = content.toRowScopeContent(icon, isTrailingIcon) ) @Composable @@ -83,10 +82,12 @@ actual fun OutlinedButton( onClick: () -> Unit, modifier: Modifier, enabled: Boolean, - content: @Composable ButtonScope.() -> Unit + icon: @Composable ((Modifier) -> Unit)?, + isTrailingIcon: Boolean, + content: @Composable () -> Unit ) = androidx.compose.material3.OutlinedButton( - onClick, modifier.platformModifier, enabled, content = content.toButtonScopeContent() + onClick, modifier.platformModifier, enabled, content = content.toRowScopeContent(icon, isTrailingIcon) ) @Composable @@ -94,15 +95,10 @@ actual fun TextButton( onClick: () -> Unit, modifier: Modifier, enabled: Boolean, - content: @Composable ButtonScope.() -> Unit + icon: @Composable ((Modifier) -> Unit)?, + isTrailingIcon: Boolean, + content: @Composable () -> Unit ) = androidx.compose.material3.TextButton( - onClick, modifier.platformModifier, enabled, content = content.toButtonScopeContent() + onClick, modifier.platformModifier, enabled, content = content.toRowScopeContent(icon, isTrailingIcon) ) - -actual object ButtonScope { - @Composable - actual fun Icon() { - TODO() - } -} diff --git a/compose-multiplatform-material3/src/commonMain/kotlin/com/huanshankeji/compose/material3/ext/Button.kt b/compose-multiplatform-material3/src/commonMain/kotlin/com/huanshankeji/compose/material3/ext/Button.kt index 8d11bc6b..a49b63bb 100644 --- a/compose-multiplatform-material3/src/commonMain/kotlin/com/huanshankeji/compose/material3/ext/Button.kt +++ b/compose-multiplatform-material3/src/commonMain/kotlin/com/huanshankeji/compose/material3/ext/Button.kt @@ -56,35 +56,109 @@ expect fun ElevatedButton( onClick: () -> Unit, modifier: Modifier = Modifier, enabled: Boolean = true, - content: @Composable ButtonScope.() -> Unit + icon: @Composable ((Modifier) -> Unit)? = null, + isTrailingIcon: Boolean = false, + content: @Composable () -> Unit ) +@Composable +fun ElevatedButtonWithMaterialIcon( + onClick: () -> Unit, + modifier: Modifier = Modifier, + enabled: Boolean = true, + icon: Icon?, + isTrailingIcon: Boolean = false, + content: @Composable () -> Unit +) = + ElevatedButton( + onClick, + modifier, + enabled, + icon?.let { { modifier -> Icon(it, null, modifier) } }, + isTrailingIcon, + content + ) + @Composable expect fun FilledTonalButton( onClick: () -> Unit, modifier: Modifier = Modifier, enabled: Boolean = true, - content: @Composable ButtonScope.() -> Unit + icon: @Composable ((Modifier) -> Unit)? = null, + isTrailingIcon: Boolean = false, + content: @Composable () -> Unit ) +@Composable +fun FilledTonalButtonWithMaterialIcon( + onClick: () -> Unit, + modifier: Modifier = Modifier, + enabled: Boolean = true, + icon: Icon?, + isTrailingIcon: Boolean = false, + content: @Composable () -> Unit +) = + FilledTonalButton( + onClick, + modifier, + enabled, + icon?.let { { modifier -> Icon(it, null, modifier) } }, + isTrailingIcon, + content + ) + @Composable expect fun OutlinedButton( onClick: () -> Unit, modifier: Modifier = Modifier, enabled: Boolean = true, - content: @Composable ButtonScope.() -> Unit + icon: @Composable ((Modifier) -> Unit)? = null, + isTrailingIcon: Boolean = false, + content: @Composable () -> Unit ) +@Composable +fun OutlinedButtonWithMaterialIcon( + onClick: () -> Unit, + modifier: Modifier = Modifier, + enabled: Boolean = true, + icon: Icon?, + isTrailingIcon: Boolean = false, + content: @Composable () -> Unit +) = + OutlinedButton( + onClick, + modifier, + enabled, + icon?.let { { modifier -> Icon(it, null, modifier) } }, + isTrailingIcon, + content + ) + @Composable expect fun TextButton( onClick: () -> Unit, modifier: Modifier = Modifier, enabled: Boolean = true, - content: @Composable ButtonScope.() -> Unit + icon: @Composable ((Modifier) -> Unit)? = null, + isTrailingIcon: Boolean = false, + content: @Composable () -> Unit ) -// TODO remove -expect class ButtonScope { - @Composable - fun Icon(/* TODO */) -} +@Composable +fun TextButtonWithMaterialIcon( + onClick: () -> Unit, + modifier: Modifier = Modifier, + enabled: Boolean = true, + icon: Icon?, + isTrailingIcon: Boolean = false, + content: @Composable () -> Unit +) = + TextButton( + onClick, + modifier, + enabled, + icon?.let { { modifier -> Icon(it, null, modifier) } }, + isTrailingIcon, + content + ) diff --git a/compose-multiplatform-material3/src/jsMain/kotlin/com/huanshankeji/compose/material3/Button.js.kt b/compose-multiplatform-material3/src/jsMain/kotlin/com/huanshankeji/compose/material3/Button.js.kt index 68fc434e..dacf5e87 100644 --- a/compose-multiplatform-material3/src/jsMain/kotlin/com/huanshankeji/compose/material3/Button.js.kt +++ b/compose-multiplatform-material3/src/jsMain/kotlin/com/huanshankeji/compose/material3/Button.js.kt @@ -51,10 +51,12 @@ internal fun CommonElevatedButton( onClick: () -> Unit, modifier: Modifier, enabled: Boolean, + isTrailingIcon: Boolean = false, content: @Composable MdButtonScope.() -> Unit ) = MdElevatedButton( disabled = enabled.isFalseOrNull(), + trailingIcon = isTrailingIcon.isTrueOrNull(), attrs = modifier.toButtonAttrs(onClick), content = content ) @@ -66,17 +68,19 @@ actual fun ElevatedButton( enabled: Boolean, content: @Composable RowScope.() -> Unit ) = - CommonElevatedButton(onClick, modifier, enabled, content.toMdButtonScopeContent()) + CommonElevatedButton(onClick, modifier, enabled, content = content.toMdButtonScopeContent()) @Composable internal fun CommonFilledTonalButton( onClick: () -> Unit, modifier: Modifier, enabled: Boolean, + isTrailingIcon: Boolean = false, content: @Composable MdButtonScope.() -> Unit ) = MdFilledTonalButton( disabled = enabled.isFalseOrNull(), + trailingIcon = isTrailingIcon.isTrueOrNull(), attrs = modifier.toButtonAttrs(onClick), content = content ) @@ -88,17 +92,19 @@ actual fun FilledTonalButton( enabled: Boolean, content: @Composable RowScope.() -> Unit ) = - CommonFilledTonalButton(onClick, modifier, enabled, content.toMdButtonScopeContent()) + CommonFilledTonalButton(onClick, modifier, enabled, content = content.toMdButtonScopeContent()) @Composable internal fun CommonOutlinedButton( onClick: () -> Unit, modifier: Modifier, enabled: Boolean, + isTrailingIcon: Boolean = false, content: @Composable MdButtonScope.() -> Unit ) = MdOutlinedButton( disabled = enabled.isFalseOrNull(), + trailingIcon = isTrailingIcon.isTrueOrNull(), attrs = modifier.toButtonAttrs(onClick), content = content ) @@ -110,17 +116,19 @@ actual fun OutlinedButton( enabled: Boolean, content: @Composable RowScope.() -> Unit ) = - CommonOutlinedButton(onClick, modifier, enabled, content.toMdButtonScopeContent()) + CommonOutlinedButton(onClick, modifier, enabled, content = content.toMdButtonScopeContent()) @Composable internal fun CommonTextButton( onClick: () -> Unit, modifier: Modifier, enabled: Boolean, + isTrailingIcon: Boolean = false, content: @Composable MdButtonScope.() -> Unit ) = MdTextButton( disabled = enabled.isFalseOrNull(), + trailingIcon = isTrailingIcon.isTrueOrNull(), attrs = modifier.toButtonAttrs(onClick), content = content ) @@ -132,4 +140,4 @@ actual fun TextButton( enabled: Boolean, content: @Composable RowScope.() -> Unit ) = - CommonTextButton(onClick, modifier, enabled, content.toMdButtonScopeContent()) + CommonTextButton(onClick, modifier, enabled, content = content.toMdButtonScopeContent()) diff --git a/compose-multiplatform-material3/src/jsMain/kotlin/com/huanshankeji/compose/material3/ext/Button.js.kt b/compose-multiplatform-material3/src/jsMain/kotlin/com/huanshankeji/compose/material3/ext/Button.js.kt index b4755694..77029b55 100644 --- a/compose-multiplatform-material3/src/jsMain/kotlin/com/huanshankeji/compose/material3/ext/Button.js.kt +++ b/compose-multiplatform-material3/src/jsMain/kotlin/com/huanshankeji/compose/material3/ext/Button.js.kt @@ -8,9 +8,14 @@ import com.huanshankeji.compose.ui.toCommonModifier import com.varabyte.kobweb.compose.ui.attrsModifier import com.varabyte.kobweb.compose.ui.Modifier as PlatformModifier -@Composable -private fun (@Composable (ButtonScope.() -> Unit)).toMdButtonScopeContent(): @Composable MdButtonScope.() -> Unit = - { ButtonScope(this).(this@toMdButtonScopeContent)() } +private fun (@Composable () -> Unit).toMdButtonScopeContent( + icon: @Composable ((Modifier) -> Unit)? +): @Composable MdButtonScope.() -> Unit = { + // see https://github.com/material-components/material-web/blob/main/docs/components/button.md#icon + + this@toMdButtonScopeContent() + icon?.invoke(PlatformModifier.attrsModifier { slotEqIcon() }.toCommonModifier()) +} @Composable @@ -22,50 +27,49 @@ actual fun Button( isTrailingIcon: Boolean, content: @Composable () -> Unit ) = - CommonButton(onClick, modifier, enabled) { - content() - icon?.invoke(PlatformModifier.attrsModifier { slotEqIcon() }.toCommonModifier()) - } + CommonButton(onClick, modifier, enabled, isTrailingIcon, content.toMdButtonScopeContent(icon)) + @Composable actual fun ElevatedButton( onClick: () -> Unit, modifier: Modifier, enabled: Boolean, - content: @Composable ButtonScope.() -> Unit + icon: @Composable ((Modifier) -> Unit)?, + isTrailingIcon: Boolean, + content: @Composable () -> Unit ) = - CommonElevatedButton(onClick, modifier, enabled, content.toMdButtonScopeContent()) + CommonElevatedButton(onClick, modifier, enabled, isTrailingIcon, content.toMdButtonScopeContent(icon)) @Composable actual fun FilledTonalButton( onClick: () -> Unit, modifier: Modifier, enabled: Boolean, - content: @Composable ButtonScope.() -> Unit + icon: @Composable ((Modifier) -> Unit)?, + isTrailingIcon: Boolean, + content: @Composable () -> Unit ) = - CommonFilledTonalButton(onClick, modifier, enabled, content.toMdButtonScopeContent()) + CommonFilledTonalButton(onClick, modifier, enabled, isTrailingIcon, content.toMdButtonScopeContent(icon)) @Composable actual fun OutlinedButton( onClick: () -> Unit, modifier: Modifier, enabled: Boolean, - content: @Composable ButtonScope.() -> Unit + icon: @Composable ((Modifier) -> Unit)?, + isTrailingIcon: Boolean, + content: @Composable () -> Unit ) = - CommonOutlinedButton(onClick, modifier, enabled, content.toMdButtonScopeContent()) + CommonOutlinedButton(onClick, modifier, enabled, isTrailingIcon, content.toMdButtonScopeContent(icon)) @Composable actual fun TextButton( onClick: () -> Unit, modifier: Modifier, enabled: Boolean, - content: @Composable ButtonScope.() -> Unit + icon: @Composable ((Modifier) -> Unit)?, + isTrailingIcon: Boolean, + content: @Composable () -> Unit ) = - CommonTextButton(onClick, modifier, enabled, content.toMdButtonScopeContent()) - -actual class ButtonScope(val mdButtonScope: MdButtonScope) { - @Composable - actual fun Icon() { - TODO() - } -} + CommonTextButton(onClick, modifier, enabled, isTrailingIcon, content.toMdButtonScopeContent(icon)) diff --git a/demo/src/commonMain/kotlin/com/huanshankeji/compose/material/demo/Material3.kt b/demo/src/commonMain/kotlin/com/huanshankeji/compose/material/demo/Material3.kt index c07dcd24..ae9f323d 100644 --- a/demo/src/commonMain/kotlin/com/huanshankeji/compose/material/demo/Material3.kt +++ b/demo/src/commonMain/kotlin/com/huanshankeji/compose/material/demo/Material3.kt @@ -27,16 +27,16 @@ fun Material3() { InlineBasicText(count.toString()) // TODO use `com.huanshankeji.compose.material3.ext.InlineText` } val rowScopeButtonContent: @Composable RowScope.() -> Unit = { buttonContent() } - val buttonScopeButtonContent: @Composable ButtonScope.() -> Unit = { buttonContent() } Row { RowScopeButton(onClick, content = rowScopeButtonContent) Button(onClick, content = buttonContent) - ElevatedButton(onClick, content = buttonScopeButtonContent) - FilledTonalButton(onClick, content = buttonScopeButtonContent) - OutlinedButton(onClick, content = buttonScopeButtonContent) - TextButton(onClick, content = buttonScopeButtonContent) + ElevatedButton(onClick, content = buttonContent) + FilledTonalButton(onClick, content = buttonContent) + OutlinedButton(onClick, content = buttonContent) + TextButton(onClick, content = buttonContent) ButtonWithMaterialIcon(onClick, icon = Icons.Default.Add, content = buttonContent) + ButtonWithMaterialIcon(onClick, icon = Icons.Default.Add, isTrailingIcon = true, content = buttonContent) } Row { From f481840bfc67a5ab983e6ea5ac1bfc0a34cb65bf Mon Sep 17 00:00:00 2001 From: Shreck Ye Date: Sat, 4 May 2024 00:44:06 +0800 Subject: [PATCH 53/75] Remove `TextField` in the `ext` package to avoid confusion caused by too many similar functions and rename the following `TextFieldWithModifierPassedToIcon` to `TextField`, and do the same to the similar `OutlinedTextField` composables See the resolved and removed TODO for more details. --- .../material3/ext/TextField.androidxCommon.kt | 182 +----------------- .../compose/material3/ext/TextField.kt | 112 +++++------ .../compose/material3/ext/TextField.js.kt | 169 ---------------- 3 files changed, 61 insertions(+), 402 deletions(-) diff --git a/compose-multiplatform-material3/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material3/ext/TextField.androidxCommon.kt b/compose-multiplatform-material3/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material3/ext/TextField.androidxCommon.kt index e16f0e44..84432b15 100644 --- a/compose-multiplatform-material3/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material3/ext/TextField.androidxCommon.kt +++ b/compose-multiplatform-material3/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material3/ext/TextField.androidxCommon.kt @@ -5,8 +5,6 @@ import androidx.compose.runtime.Composable import com.huanshankeji.compose.foundation.text.KeyboardActions import com.huanshankeji.compose.foundation.text.KeyboardOptions import com.huanshankeji.compose.foundation.text.toPlatformValue -import com.huanshankeji.compose.material.icons.Icon -import com.huanshankeji.compose.material3.Icon import com.huanshankeji.compose.ui.Modifier // This function can be moved into a common file. @@ -16,9 +14,6 @@ fun String?.ToNullableTextComposable(): (@Composable () -> Unit)? = private fun (@Composable ((Modifier) -> Unit)?).toContentWithoutModifier(): @Composable (() -> Unit)? = this?.let { { it(Modifier) } } -private fun Icon?.toIconContent(): @Composable (() -> Unit)? = - this?.let { { Icon(it, null) } } - @Composable actual fun TextField( @@ -29,8 +24,8 @@ actual fun TextField( readOnly: Boolean, label: String?, placeholder: String?, - leadingIcon: @Composable (() -> Unit)?, - trailingIcon: @Composable (() -> Unit)?, + leadingIcon: @Composable ((Modifier) -> Unit)?, + trailingIcon: @Composable ((Modifier) -> Unit)?, prefix: String?, suffix: String?, supportingText: String?, @@ -48,8 +43,8 @@ actual fun TextField( readOnly, label = label.ToNullableTextComposable(), placeholder = placeholder.ToNullableTextComposable(), - leadingIcon = leadingIcon, - trailingIcon = trailingIcon, + leadingIcon = leadingIcon.toContentWithoutModifier(), + trailingIcon = trailingIcon.toContentWithoutModifier(), prefix = prefix.ToNullableTextComposable(), suffix = suffix.ToNullableTextComposable(), supportingText = supportingText.ToNullableTextComposable(), @@ -61,87 +56,6 @@ actual fun TextField( minLines = lines ) -@Composable -actual fun TextFieldWithModifierPassedToIcon( - value: String, - onValueChange: (String) -> Unit, - modifier: Modifier, - enabled: Boolean, - readOnly: Boolean, - label: String?, - placeholder: String?, - leadingIcon: @Composable ((Modifier) -> Unit)?, - trailingIcon: @Composable ((Modifier) -> Unit)?, - prefix: String?, - suffix: String?, - supportingText: String?, - isError: Boolean, - keyboardOptions: KeyboardOptions, - keyboardActions: KeyboardActions, - singleLine: Boolean, - lines: Int -) = - TextField( - value, - onValueChange, - modifier, - enabled, - readOnly, - label, - placeholder, - leadingIcon.toContentWithoutModifier(), - trailingIcon.toContentWithoutModifier(), - prefix, - suffix, - supportingText, - isError, - keyboardOptions, - keyboardActions, - singleLine, - lines - ) - - -@Composable -actual fun TextFieldWithMaterialIcons( - value: String, - onValueChange: (String) -> Unit, - modifier: Modifier, - enabled: Boolean, - readOnly: Boolean, - label: String?, - placeholder: String?, - leadingIcon: Icon?, - trailingIcon: Icon?, - prefix: String?, - suffix: String?, - supportingText: String?, - isError: Boolean, - keyboardOptions: KeyboardOptions, - keyboardActions: KeyboardActions, - singleLine: Boolean, - lines: Int -) = - TextField( - value, - onValueChange, - modifier, - enabled, - readOnly, - label, - placeholder, - leadingIcon.toIconContent(), - trailingIcon.toIconContent(), - prefix, - suffix, - supportingText, - isError, - keyboardOptions, - keyboardActions, - singleLine, - lines - ) - @Composable actual fun OutlinedTextField( @@ -152,8 +66,8 @@ actual fun OutlinedTextField( readOnly: Boolean, label: String?, placeholder: String?, - leadingIcon: @Composable (() -> Unit)?, - trailingIcon: @Composable (() -> Unit)?, + leadingIcon: @Composable ((Modifier) -> Unit)?, + trailingIcon: @Composable ((Modifier) -> Unit)?, prefix: String?, suffix: String?, supportingText: String?, @@ -171,8 +85,8 @@ actual fun OutlinedTextField( readOnly, label = label.ToNullableTextComposable(), placeholder = placeholder.ToNullableTextComposable(), - leadingIcon = leadingIcon, - trailingIcon = trailingIcon, + leadingIcon = leadingIcon.toContentWithoutModifier(), + trailingIcon = trailingIcon.toContentWithoutModifier(), prefix = prefix.ToNullableTextComposable(), suffix = suffix.ToNullableTextComposable(), supportingText = supportingText.ToNullableTextComposable(), @@ -183,83 +97,3 @@ actual fun OutlinedTextField( maxLines = lines, minLines = lines ) - -@Composable -actual fun OutlinedTextFieldWithModifierPassedToIcon( - value: String, - onValueChange: (String) -> Unit, - modifier: Modifier, - enabled: Boolean, - readOnly: Boolean, - label: String?, - placeholder: String?, - leadingIcon: @Composable ((Modifier) -> Unit)?, - trailingIcon: @Composable ((Modifier) -> Unit)?, - prefix: String?, - suffix: String?, - supportingText: String?, - isError: Boolean, - keyboardOptions: KeyboardOptions, - keyboardActions: KeyboardActions, - singleLine: Boolean, - lines: Int -) = - OutlinedTextField( - value, - onValueChange, - modifier, - enabled, - readOnly, - label, - placeholder, - leadingIcon.toContentWithoutModifier(), - trailingIcon.toContentWithoutModifier(), - prefix, - suffix, - supportingText, - isError, - keyboardOptions, - keyboardActions, - singleLine, - lines - ) - -@Composable -actual fun OutlinedTextFieldWithMaterialIcons( - value: String, - onValueChange: (String) -> Unit, - modifier: Modifier, - enabled: Boolean, - readOnly: Boolean, - label: String?, - placeholder: String?, - leadingIcon: Icon?, - trailingIcon: Icon?, - prefix: String?, - suffix: String?, - supportingText: String?, - isError: Boolean, - keyboardOptions: KeyboardOptions, - keyboardActions: KeyboardActions, - singleLine: Boolean, - lines: Int -) = - OutlinedTextField( - value, - onValueChange, - modifier, - enabled, - readOnly, - label, - placeholder, - leadingIcon.toIconContent(), - trailingIcon.toIconContent(), - prefix, - suffix, - supportingText, - isError, - keyboardOptions, - keyboardActions, - singleLine, - lines - ) diff --git a/compose-multiplatform-material3/src/commonMain/kotlin/com/huanshankeji/compose/material3/ext/TextField.kt b/compose-multiplatform-material3/src/commonMain/kotlin/com/huanshankeji/compose/material3/ext/TextField.kt index eaa0749d..4650195d 100644 --- a/compose-multiplatform-material3/src/commonMain/kotlin/com/huanshankeji/compose/material3/ext/TextField.kt +++ b/compose-multiplatform-material3/src/commonMain/kotlin/com/huanshankeji/compose/material3/ext/TextField.kt @@ -4,47 +4,19 @@ import androidx.compose.runtime.Composable import com.huanshankeji.compose.foundation.text.KeyboardActions import com.huanshankeji.compose.foundation.text.KeyboardOptions import com.huanshankeji.compose.material.icons.Icon +import com.huanshankeji.compose.material3.Icon import com.huanshankeji.compose.ui.Modifier -/* -TODO Remove this to avoid confusion caused by too many similar functions, and rename the following `TextFieldWithModifierPassedToIcon` to `TextField`. - Do the same to the similar `OutlinedTextField`. - This function was added in order to be more akin to the `androidx.compose.material3` one, but it seems unnecessary now on second thought. - The user should be recommended to pass the `Modifier` for the component to work better on JS. - The newly-refactored `ext` button composables are designed in this way. - */ -@Composable -expect fun TextField( - value: String, - onValueChange: (String) -> Unit, - modifier: Modifier = Modifier, - enabled: Boolean = true, - readOnly: Boolean = false, - label: String? = null, - placeholder: String? = null, - leadingIcon: @Composable (() -> Unit)? = null, - trailingIcon: @Composable (() -> Unit)? = null, - prefix: String? = null, - suffix: String? = null, - supportingText: String? = null, - isError: Boolean = false, - keyboardOptions: KeyboardOptions = KeyboardOptions.Default, - keyboardActions: KeyboardActions = KeyboardActions.Default, - singleLine: Boolean = false, - lines: Int = 1 - /* - maxLines: Int = if (singleLine) 1 else Int.MAX_VALUE, - minLines: Int = 1 - */ - // pattern: String? // This can be supported with Kotlin's `Regex` so it's not supported here. -) +private fun Icon?.toIconContentWithModifier(): @Composable ((Modifier) -> Unit)? = + this?.let { { modifier -> Icon(it, null, modifier) } } + /** * @param leadingIcon the [Modifier] parameter contains the attributes to be set on this icon on JS. You are supposed to pass this [Modifier] to the top-level composable that you invoke inside. * @param trailingIcon ditto. */ @Composable -expect fun TextFieldWithModifierPassedToIcon( +expect fun TextField( value: String, onValueChange: (String) -> Unit, modifier: Modifier = Modifier, @@ -62,10 +34,15 @@ expect fun TextFieldWithModifierPassedToIcon( keyboardActions: KeyboardActions = KeyboardActions.Default, singleLine: Boolean = false, lines: Int = 1 + /* + maxLines: Int = if (singleLine) 1 else Int.MAX_VALUE, + minLines: Int = 1 + */ + // pattern: String? // This can be supported with Kotlin's `Regex` so it's not supported here. ) @Composable -expect fun TextFieldWithMaterialIcons( +fun TextFieldWithMaterialIcons( value: String, onValueChange: (String) -> Unit, modifier: Modifier = Modifier, @@ -83,36 +60,34 @@ expect fun TextFieldWithMaterialIcons( keyboardActions: KeyboardActions = KeyboardActions.Default, singleLine: Boolean = false, lines: Int = 1 -) - +) = + TextField( + value, + onValueChange, + modifier, + enabled, + readOnly, + label, + placeholder, + leadingIcon.toIconContentWithModifier(), + trailingIcon.toIconContentWithModifier(), + prefix, + suffix, + supportingText, + isError, + keyboardOptions, + keyboardActions, + singleLine, + lines + ) -@Composable -expect fun OutlinedTextField( - value: String, - onValueChange: (String) -> Unit, - modifier: Modifier = Modifier, - enabled: Boolean = true, - readOnly: Boolean = false, - label: String? = null, - placeholder: String? = null, - leadingIcon: @Composable (() -> Unit)? = null, - trailingIcon: @Composable (() -> Unit)? = null, - prefix: String? = null, - suffix: String? = null, - supportingText: String? = null, - isError: Boolean = false, - keyboardOptions: KeyboardOptions = KeyboardOptions.Default, - keyboardActions: KeyboardActions = KeyboardActions.Default, - singleLine: Boolean = false, - lines: Int = 1 -) /** * @param leadingIcon the [Modifier] parameter contains the attributes to be set on this icon on JS. You are supposed to pass this [Modifier] to the top-level composable that you invoke inside. * @param trailingIcon ditto. */ @Composable -expect fun OutlinedTextFieldWithModifierPassedToIcon( +expect fun OutlinedTextField( value: String, onValueChange: (String) -> Unit, modifier: Modifier = Modifier, @@ -133,7 +108,7 @@ expect fun OutlinedTextFieldWithModifierPassedToIcon( ) @Composable -expect fun OutlinedTextFieldWithMaterialIcons( +fun OutlinedTextFieldWithMaterialIcons( value: String, onValueChange: (String) -> Unit, modifier: Modifier = Modifier, @@ -151,4 +126,23 @@ expect fun OutlinedTextFieldWithMaterialIcons( keyboardActions: KeyboardActions = KeyboardActions.Default, singleLine: Boolean = false, lines: Int = 1 -) +) = + OutlinedTextField( + value, + onValueChange, + modifier, + enabled, + readOnly, + label, + placeholder, + leadingIcon.toIconContentWithModifier(), + trailingIcon.toIconContentWithModifier(), + prefix, + suffix, + supportingText, + isError, + keyboardOptions, + keyboardActions, + singleLine, + lines + ) diff --git a/compose-multiplatform-material3/src/jsMain/kotlin/com/huanshankeji/compose/material3/ext/TextField.js.kt b/compose-multiplatform-material3/src/jsMain/kotlin/com/huanshankeji/compose/material3/ext/TextField.js.kt index 435220ec..2bef9237 100644 --- a/compose-multiplatform-material3/src/jsMain/kotlin/com/huanshankeji/compose/material3/ext/TextField.js.kt +++ b/compose-multiplatform-material3/src/jsMain/kotlin/com/huanshankeji/compose/material3/ext/TextField.js.kt @@ -1,15 +1,12 @@ package com.huanshankeji.compose.material3.ext import androidx.compose.runtime.Composable -import com.huanshankeji.compose.foundation.layout.Box import com.huanshankeji.compose.foundation.text.KeyboardActions import com.huanshankeji.compose.foundation.text.KeyboardOptions import com.huanshankeji.compose.foundation.text.attrsFrom import com.huanshankeji.compose.html.material3.MdFilledTextField import com.huanshankeji.compose.html.material3.MdOutlinedTextField import com.huanshankeji.compose.html.material3.MdTextFieldScope -import com.huanshankeji.compose.material.icons.Icon -import com.huanshankeji.compose.material3.Icon import com.huanshankeji.compose.ui.Modifier import com.huanshankeji.compose.ui.toCommonModifier import com.huanshankeji.compose.web.attributes.ext.onInput @@ -41,55 +38,9 @@ private fun TextFieldContent( trailingIcon?.invoke(PlatformModifier.attrsModifier { slot(MdTextFieldScope.Slot.TrailingIcon) }.toCommonModifier()) } -private fun (@Composable (() -> Unit)?).toBoxedContentWithModifier(): @Composable ((Modifier) -> Unit)? = - this?.let { { modifier -> Box(modifier) { it() } } } - -private fun Icon?.toIconContentWithModifier(): @Composable ((Modifier) -> Unit)? = - this?.let { { modifier -> Icon(it, null, modifier) } } - @Composable actual fun TextField( - value: String, - onValueChange: (String) -> Unit, - modifier: Modifier, - enabled: Boolean, - readOnly: Boolean, - label: String?, - placeholder: String?, - leadingIcon: @Composable (() -> Unit)?, - trailingIcon: @Composable (() -> Unit)?, - prefix: String?, - suffix: String?, - supportingText: String?, - isError: Boolean, - keyboardOptions: KeyboardOptions, - keyboardActions: KeyboardActions, - singleLine: Boolean, - lines: Int -) = - TextFieldWithModifierPassedToIcon( - value, - onValueChange, - modifier, - enabled, - readOnly, - label, - placeholder, - leadingIcon.toBoxedContentWithModifier(), - trailingIcon.toBoxedContentWithModifier(), - prefix, - suffix, - supportingText, - isError, - keyboardOptions, - keyboardActions, - singleLine, - lines - ) - -@Composable -actual fun TextFieldWithModifierPassedToIcon( value: String, onValueChange: (String) -> Unit, modifier: Modifier, @@ -127,89 +78,9 @@ actual fun TextFieldWithModifierPassedToIcon( content = TextFieldContent(leadingIcon, trailingIcon) ) -@Composable -actual fun TextFieldWithMaterialIcons( - value: String, - onValueChange: (String) -> Unit, - modifier: Modifier, - enabled: Boolean, - readOnly: Boolean, - label: String?, - placeholder: String?, - leadingIcon: Icon?, - trailingIcon: Icon?, - prefix: String?, - suffix: String?, - supportingText: String?, - isError: Boolean, - keyboardOptions: KeyboardOptions, - keyboardActions: KeyboardActions, - singleLine: Boolean, - lines: Int -) = - TextFieldWithModifierPassedToIcon( - value, - onValueChange, - modifier, - enabled, - readOnly, - label, - placeholder, - leadingIcon.toIconContentWithModifier(), - trailingIcon.toIconContentWithModifier(), - prefix, - suffix, - supportingText, - isError, - keyboardOptions, - keyboardActions, - singleLine, - lines - ) - @Composable actual fun OutlinedTextField( - value: String, - onValueChange: (String) -> Unit, - modifier: Modifier, - enabled: Boolean, - readOnly: Boolean, - label: String?, - placeholder: String?, - leadingIcon: @Composable (() -> Unit)?, - trailingIcon: @Composable (() -> Unit)?, - prefix: String?, - suffix: String?, - supportingText: String?, - isError: Boolean, - keyboardOptions: KeyboardOptions, - keyboardActions: KeyboardActions, - singleLine: Boolean, - lines: Int -) = - OutlinedTextFieldWithModifierPassedToIcon( - value, - onValueChange, - modifier, - enabled, - readOnly, - label, - placeholder, - leadingIcon.toBoxedContentWithModifier(), - trailingIcon.toBoxedContentWithModifier(), - prefix, - suffix, - supportingText, - isError, - keyboardOptions, - keyboardActions, - singleLine, - lines - ) - -@Composable -actual fun OutlinedTextFieldWithModifierPassedToIcon( value: String, onValueChange: (String) -> Unit, modifier: Modifier, @@ -246,43 +117,3 @@ actual fun OutlinedTextFieldWithModifierPassedToIcon( attrs = modifier.toTextFieldAttrs(onValueChange, keyboardOptions, keyboardActions), content = TextFieldContent(leadingIcon, trailingIcon) ) - -@Composable -actual fun OutlinedTextFieldWithMaterialIcons( - value: String, - onValueChange: (String) -> Unit, - modifier: Modifier, - enabled: Boolean, - readOnly: Boolean, - label: String?, - placeholder: String?, - leadingIcon: Icon?, - trailingIcon: Icon?, - prefix: String?, - suffix: String?, - supportingText: String?, - isError: Boolean, - keyboardOptions: KeyboardOptions, - keyboardActions: KeyboardActions, - singleLine: Boolean, - lines: Int -) = - OutlinedTextFieldWithModifierPassedToIcon( - value, - onValueChange, - modifier, - enabled, - readOnly, - label, - placeholder, - leadingIcon.toIconContentWithModifier(), - trailingIcon.toIconContentWithModifier(), - prefix, - suffix, - supportingText, - isError, - keyboardOptions, - keyboardActions, - singleLine, - lines - ) From cb12bd8bbbccec2d4e7476e468ad364a9c2d5648 Mon Sep 17 00:00:00 2001 From: Shreck Ye Date: Sat, 4 May 2024 01:42:49 +0800 Subject: [PATCH 54/75] Copy and adapt the text composable from the Material 2 module to the Material 3 module --- .../compose/material3/Text.androidxCommon.kt | 8 ++++++++ .../material3/ext/Text.androidxCommon.kt | 8 ++++++++ .../huanshankeji/compose/material3/Text.kt | 14 ++++++++++++++ .../compose/material3/ext/Text.kt | 19 +++++++++++++++++++ .../huanshankeji/compose/material3/Text.js.kt | 9 +++++++++ .../compose/material3/ext/Text.js.kt | 8 ++++++++ .../compose/material/demo/Material3.kt | 3 +-- 7 files changed, 67 insertions(+), 2 deletions(-) create mode 100644 compose-multiplatform-material3/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material3/Text.androidxCommon.kt create mode 100644 compose-multiplatform-material3/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material3/ext/Text.androidxCommon.kt create mode 100644 compose-multiplatform-material3/src/commonMain/kotlin/com/huanshankeji/compose/material3/Text.kt create mode 100644 compose-multiplatform-material3/src/commonMain/kotlin/com/huanshankeji/compose/material3/ext/Text.kt create mode 100644 compose-multiplatform-material3/src/jsMain/kotlin/com/huanshankeji/compose/material3/Text.js.kt create mode 100644 compose-multiplatform-material3/src/jsMain/kotlin/com/huanshankeji/compose/material3/ext/Text.js.kt diff --git a/compose-multiplatform-material3/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material3/Text.androidxCommon.kt b/compose-multiplatform-material3/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material3/Text.androidxCommon.kt new file mode 100644 index 00000000..2bbe2f8e --- /dev/null +++ b/compose-multiplatform-material3/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material3/Text.androidxCommon.kt @@ -0,0 +1,8 @@ +package com.huanshankeji.compose.material3 + +import androidx.compose.runtime.Composable +import com.huanshankeji.compose.ui.Modifier + +@Composable +actual fun Text(text: String, modifier: Modifier) = + androidx.compose.material3.Text(text, modifier.platformModifier) diff --git a/compose-multiplatform-material3/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material3/ext/Text.androidxCommon.kt b/compose-multiplatform-material3/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material3/ext/Text.androidxCommon.kt new file mode 100644 index 00000000..4fcc7557 --- /dev/null +++ b/compose-multiplatform-material3/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material3/ext/Text.androidxCommon.kt @@ -0,0 +1,8 @@ +package com.huanshankeji.compose.material3.ext + +import androidx.compose.runtime.Composable +import com.huanshankeji.compose.material3.Text + +@Composable +actual fun InlineText(text: String) = + Text(text) diff --git a/compose-multiplatform-material3/src/commonMain/kotlin/com/huanshankeji/compose/material3/Text.kt b/compose-multiplatform-material3/src/commonMain/kotlin/com/huanshankeji/compose/material3/Text.kt new file mode 100644 index 00000000..13dfb570 --- /dev/null +++ b/compose-multiplatform-material3/src/commonMain/kotlin/com/huanshankeji/compose/material3/Text.kt @@ -0,0 +1,14 @@ +package com.huanshankeji.compose.material3 + +import androidx.compose.runtime.Composable +import com.huanshankeji.compose.ui.Modifier + +/** + * The `com.huanshankeji.compose.material.Text` function + * can be easily confused with other Composable functions named `Text` + * such as `androidx.compose.material.Text` and `org.jetbrains.compose.web.dom.Text` + * if not careful. + * @see com.huanshankeji.compose.material3.ext.MaterialText + */ +@Composable +expect fun Text(text: String, modifier: Modifier = Modifier) diff --git a/compose-multiplatform-material3/src/commonMain/kotlin/com/huanshankeji/compose/material3/ext/Text.kt b/compose-multiplatform-material3/src/commonMain/kotlin/com/huanshankeji/compose/material3/ext/Text.kt new file mode 100644 index 00000000..0e10df5f --- /dev/null +++ b/compose-multiplatform-material3/src/commonMain/kotlin/com/huanshankeji/compose/material3/ext/Text.kt @@ -0,0 +1,19 @@ +package com.huanshankeji.compose.material3.ext + +import androidx.compose.runtime.Composable +import com.huanshankeji.compose.material3.Text +import com.huanshankeji.compose.ui.Modifier + +/** + * An explicit alias of [Text]. + */ +@Composable +inline fun MaterialText(text: String, modifier: Modifier = Modifier) = + Text(text, modifier) + +/** + * Delegates to raw inline text without any element on JS / Compose HTML. + * @see com.huanshankeji.compose.foundation.text.ext.InlineBasicText + */ +@Composable +expect fun InlineText(text: String) diff --git a/compose-multiplatform-material3/src/jsMain/kotlin/com/huanshankeji/compose/material3/Text.js.kt b/compose-multiplatform-material3/src/jsMain/kotlin/com/huanshankeji/compose/material3/Text.js.kt new file mode 100644 index 00000000..4d8e536a --- /dev/null +++ b/compose-multiplatform-material3/src/jsMain/kotlin/com/huanshankeji/compose/material3/Text.js.kt @@ -0,0 +1,9 @@ +package com.huanshankeji.compose.material3 + +import androidx.compose.runtime.Composable +import com.huanshankeji.compose.foundation.text.BasicText +import com.huanshankeji.compose.ui.Modifier + +@Composable +actual fun Text(text: String, modifier: Modifier) = + BasicText(text, modifier) diff --git a/compose-multiplatform-material3/src/jsMain/kotlin/com/huanshankeji/compose/material3/ext/Text.js.kt b/compose-multiplatform-material3/src/jsMain/kotlin/com/huanshankeji/compose/material3/ext/Text.js.kt new file mode 100644 index 00000000..d71b78f9 --- /dev/null +++ b/compose-multiplatform-material3/src/jsMain/kotlin/com/huanshankeji/compose/material3/ext/Text.js.kt @@ -0,0 +1,8 @@ +package com.huanshankeji.compose.material3.ext + +import androidx.compose.runtime.Composable +import org.jetbrains.compose.web.dom.Text + +@Composable +actual fun InlineText(text: String) = + Text(text) diff --git a/demo/src/commonMain/kotlin/com/huanshankeji/compose/material/demo/Material3.kt b/demo/src/commonMain/kotlin/com/huanshankeji/compose/material/demo/Material3.kt index ae9f323d..b7a39497 100644 --- a/demo/src/commonMain/kotlin/com/huanshankeji/compose/material/demo/Material3.kt +++ b/demo/src/commonMain/kotlin/com/huanshankeji/compose/material/demo/Material3.kt @@ -6,7 +6,6 @@ import com.huanshankeji.compose.foundation.layout.Row import com.huanshankeji.compose.foundation.layout.RowScope import com.huanshankeji.compose.foundation.text.KeyboardActions import com.huanshankeji.compose.foundation.text.KeyboardOptions -import com.huanshankeji.compose.foundation.text.ext.InlineBasicText import com.huanshankeji.compose.foundation.text.input.ImeAction import com.huanshankeji.compose.foundation.text.input.KeyboardCapitalization import com.huanshankeji.compose.foundation.text.input.KeyboardType @@ -24,7 +23,7 @@ fun Material3() { var count by remember { mutableStateOf(0) } val onClick: () -> Unit = { count++ } val buttonContent: @Composable () -> Unit = { - InlineBasicText(count.toString()) // TODO use `com.huanshankeji.compose.material3.ext.InlineText` + InlineText(count.toString()) } val rowScopeButtonContent: @Composable RowScope.() -> Unit = { buttonContent() } Row { From 4d2b665f3a2e9656da3cc73e3aa9bffb24c6b5ae Mon Sep 17 00:00:00 2001 From: Shreck Ye Date: Sat, 4 May 2024 01:46:59 +0800 Subject: [PATCH 55/75] Move the 2 buttons with icons to a separate row in the demo --- .../kotlin/com/huanshankeji/compose/material/demo/Material3.kt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/demo/src/commonMain/kotlin/com/huanshankeji/compose/material/demo/Material3.kt b/demo/src/commonMain/kotlin/com/huanshankeji/compose/material/demo/Material3.kt index b7a39497..0dfb89ab 100644 --- a/demo/src/commonMain/kotlin/com/huanshankeji/compose/material/demo/Material3.kt +++ b/demo/src/commonMain/kotlin/com/huanshankeji/compose/material/demo/Material3.kt @@ -33,7 +33,8 @@ fun Material3() { FilledTonalButton(onClick, content = buttonContent) OutlinedButton(onClick, content = buttonContent) TextButton(onClick, content = buttonContent) - + } + Row { ButtonWithMaterialIcon(onClick, icon = Icons.Default.Add, content = buttonContent) ButtonWithMaterialIcon(onClick, icon = Icons.Default.Add, isTrailingIcon = true, content = buttonContent) } From 1d92d962af2263c803ebb4a8ca40359add9634a4 Mon Sep 17 00:00:00 2001 From: Shreck Ye Date: Sun, 5 May 2024 01:38:51 +0800 Subject: [PATCH 56/75] Add the toggle button composables and test them in the demo Add an `ExtRecommendedApi` opt-in BTW. The corresponding commit: https://github.com/huanshankeji/compose-html-material/commit/6b8f505c78f9f8d7745d8744fec0b491f1ef6e70 --- .../huanshankeji/compose/ExtRecommendedApi.kt | 9 ++ .../icons/filled/Icons.androidxCommon.kt | 2 + .../compose/material/icons/filled/Icons.kt | 1 + .../compose/material/icons/filled/Icons.js.kt | 1 + .../material3/IconButton.androidxCommon.kt | 104 +++++++++++++ .../ext/IconButton.androidxCommon.kt | 80 ++++++++++ .../compose/material3/IconButton.kt | 77 ++++++++++ .../compose/material3/ext/IconButton.kt | 138 ++++++++++++++++++ .../compose/material3/IconButton.js.kt | 138 ++++++++++++++++++ .../compose/material3/ext/IconButton.js.kt | 97 ++++++++++++ .../compose/material/demo/Material3.kt | 46 +++++- 11 files changed, 687 insertions(+), 6 deletions(-) create mode 100644 compose-multiplatform-common/src/commonMain/kotlin/com/huanshankeji/compose/ExtRecommendedApi.kt create mode 100644 compose-multiplatform-material3/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material3/IconButton.androidxCommon.kt create mode 100644 compose-multiplatform-material3/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material3/ext/IconButton.androidxCommon.kt create mode 100644 compose-multiplatform-material3/src/commonMain/kotlin/com/huanshankeji/compose/material3/IconButton.kt create mode 100644 compose-multiplatform-material3/src/commonMain/kotlin/com/huanshankeji/compose/material3/ext/IconButton.kt create mode 100644 compose-multiplatform-material3/src/jsMain/kotlin/com/huanshankeji/compose/material3/IconButton.js.kt create mode 100644 compose-multiplatform-material3/src/jsMain/kotlin/com/huanshankeji/compose/material3/ext/IconButton.js.kt diff --git a/compose-multiplatform-common/src/commonMain/kotlin/com/huanshankeji/compose/ExtRecommendedApi.kt b/compose-multiplatform-common/src/commonMain/kotlin/com/huanshankeji/compose/ExtRecommendedApi.kt new file mode 100644 index 00000000..8c3ae1cb --- /dev/null +++ b/compose-multiplatform-common/src/commonMain/kotlin/com/huanshankeji/compose/ExtRecommendedApi.kt @@ -0,0 +1,9 @@ +package com.huanshankeji.compose + +@RequiresOptIn( + "This API is more akin to the original `androidx.compose` one but does not follow the conventions and cannot produce the perfect outcome on JS (Compose HTML). " + + "Consider using the corresponding alternative in the `ext` package instead if you have time to refactor the code.", + RequiresOptIn.Level.WARNING +) +@Retention(AnnotationRetention.BINARY) +annotation class ExtRecommendedApi \ No newline at end of file diff --git a/compose-multiplatform-material-icons-core/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material/icons/filled/Icons.androidxCommon.kt b/compose-multiplatform-material-icons-core/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material/icons/filled/Icons.androidxCommon.kt index 36e09347..58e5148e 100644 --- a/compose-multiplatform-material-icons-core/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material/icons/filled/Icons.androidxCommon.kt +++ b/compose-multiplatform-material-icons-core/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material/icons/filled/Icons.androidxCommon.kt @@ -2,6 +2,7 @@ package com.huanshankeji.compose.material.icons.filled import androidx.compose.material.icons.filled.Add import androidx.compose.material.icons.filled.Menu +import androidx.compose.material.icons.filled.Remove import androidx.compose.material.icons.filled.Search import com.huanshankeji.compose.material.icons.Icon import com.huanshankeji.compose.material.icons.Icons @@ -10,3 +11,4 @@ import androidx.compose.material.icons.Icons as PlatformIcons actual val Icons.Filled.Add: Icon get() = PlatformIcons.Filled.Add actual val Icons.Filled.Menu: Icon get() = PlatformIcons.Filled.Menu actual val Icons.Filled.Search: Icon get() = PlatformIcons.Filled.Search +actual val Icons.Filled.Remove: Icon get() = PlatformIcons.Filled.Remove diff --git a/compose-multiplatform-material-icons-core/src/commonMain/kotlin/com/huanshankeji/compose/material/icons/filled/Icons.kt b/compose-multiplatform-material-icons-core/src/commonMain/kotlin/com/huanshankeji/compose/material/icons/filled/Icons.kt index 52ae6ded..7fa162dc 100644 --- a/compose-multiplatform-material-icons-core/src/commonMain/kotlin/com/huanshankeji/compose/material/icons/filled/Icons.kt +++ b/compose-multiplatform-material-icons-core/src/commonMain/kotlin/com/huanshankeji/compose/material/icons/filled/Icons.kt @@ -6,3 +6,4 @@ import com.huanshankeji.compose.material.icons.Icons expect val Icons.Filled.Add: Icon expect val Icons.Filled.Menu: Icon expect val Icons.Filled.Search: Icon +expect val Icons.Filled.Remove: Icon diff --git a/compose-multiplatform-material-icons-core/src/jsMain/kotlin/com/huanshankeji/compose/material/icons/filled/Icons.js.kt b/compose-multiplatform-material-icons-core/src/jsMain/kotlin/com/huanshankeji/compose/material/icons/filled/Icons.js.kt index 422a231b..c357931b 100644 --- a/compose-multiplatform-material-icons-core/src/jsMain/kotlin/com/huanshankeji/compose/material/icons/filled/Icons.js.kt +++ b/compose-multiplatform-material-icons-core/src/jsMain/kotlin/com/huanshankeji/compose/material/icons/filled/Icons.js.kt @@ -6,3 +6,4 @@ import com.huanshankeji.compose.material.icons.Icons actual val Icons.Filled.Add: Icon get() = Icon("add") actual val Icons.Filled.Menu: Icon get() = Icon("menu") actual val Icons.Filled.Search: Icon get() = Icon("search") +actual val Icons.Filled.Remove: Icon get() = Icon("remove") diff --git a/compose-multiplatform-material3/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material3/IconButton.androidxCommon.kt b/compose-multiplatform-material3/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material3/IconButton.androidxCommon.kt new file mode 100644 index 00000000..8396c9a9 --- /dev/null +++ b/compose-multiplatform-material3/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material3/IconButton.androidxCommon.kt @@ -0,0 +1,104 @@ +package com.huanshankeji.compose.material3 + +import androidx.compose.runtime.Composable +import com.huanshankeji.compose.ui.Modifier + +@Composable +actual fun IconButton( + onClick: () -> Unit, + modifier: Modifier, + enabled: Boolean, + content: @Composable () -> Unit +) = + androidx.compose.material3.IconButton(onClick, modifier.platformModifier, enabled, content = content) + +@Composable +actual fun IconToggleButton( + checked: Boolean, + onCheckedChange: (Boolean) -> Unit, + modifier: Modifier, + enabled: Boolean, + content: @Composable () -> Unit +) = + androidx.compose.material3.IconToggleButton( + checked, + onCheckedChange, + modifier.platformModifier, + enabled, + content = content + ) + +@Composable +actual fun FilledIconButton( + onClick: () -> Unit, + modifier: Modifier, + enabled: Boolean, + content: @Composable () -> Unit +) = + androidx.compose.material3.FilledIconButton(onClick, modifier.platformModifier, enabled, content = content) + +@Composable +actual fun FilledIconToggleButton( + checked: Boolean, + onCheckedChange: (Boolean) -> Unit, + modifier: Modifier, + enabled: Boolean, + content: @Composable () -> Unit +) = + androidx.compose.material3.FilledIconToggleButton( + checked, + onCheckedChange, + modifier.platformModifier, + enabled, + content = content + ) + +@Composable +actual fun FilledTonalIconButton( + onClick: () -> Unit, + modifier: Modifier, + enabled: Boolean, + content: @Composable () -> Unit +) = + androidx.compose.material3.FilledTonalIconButton(onClick, modifier.platformModifier, enabled, content = content) + +@Composable +actual fun FilledTonalIconToggleButton( + checked: Boolean, + onCheckedChange: (Boolean) -> Unit, + modifier: Modifier, + enabled: Boolean, + content: @Composable () -> Unit +) = + androidx.compose.material3.FilledTonalIconToggleButton( + checked, + onCheckedChange, + modifier.platformModifier, + enabled, + content = content + ) + +@Composable +actual fun OutlinedIconButton( + onClick: () -> Unit, + modifier: Modifier, + enabled: Boolean, + content: @Composable () -> Unit +) = + androidx.compose.material3.OutlinedIconButton(onClick, modifier.platformModifier, enabled, content = content) + +@Composable +actual fun OutlinedIconToggleButton( + checked: Boolean, + onCheckedChange: (Boolean) -> Unit, + modifier: Modifier, + enabled: Boolean, + content: @Composable () -> Unit +) = + androidx.compose.material3.OutlinedIconToggleButton( + checked, + onCheckedChange, + modifier.platformModifier, + enabled, + content = content + ) diff --git a/compose-multiplatform-material3/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material3/ext/IconButton.androidxCommon.kt b/compose-multiplatform-material3/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material3/ext/IconButton.androidxCommon.kt new file mode 100644 index 00000000..54cf3d71 --- /dev/null +++ b/compose-multiplatform-material3/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material3/ext/IconButton.androidxCommon.kt @@ -0,0 +1,80 @@ +package com.huanshankeji.compose.material3.ext + +import androidx.compose.runtime.Composable +import com.huanshankeji.compose.ui.Modifier + +private fun commonIconToggleButtonContent( + checked: Boolean, + checkedContent: @Composable (Modifier) -> Unit, + uncheckedContent: @Composable () -> Unit +): @Composable () -> Unit = { + if (checked) checkedContent(Modifier) else uncheckedContent() +} + +@Composable +actual fun IconToggleButton( + checked: Boolean, + onCheckedChange: (Boolean) -> Unit, + modifier: Modifier, + enabled: Boolean, + uncheckedContent: @Composable () -> Unit, + checkedContent: @Composable (Modifier) -> Unit +) = + com.huanshankeji.compose.material3.IconToggleButton( + checked, + onCheckedChange, + modifier, + enabled, + commonIconToggleButtonContent(checked, checkedContent, uncheckedContent) + ) + +@Composable +actual fun FilledIconToggleButton( + checked: Boolean, + onCheckedChange: (Boolean) -> Unit, + modifier: Modifier, + enabled: Boolean, + uncheckedContent: @Composable () -> Unit, + checkedContent: @Composable (Modifier) -> Unit +) = + com.huanshankeji.compose.material3.FilledIconToggleButton( + checked, + onCheckedChange, + modifier, + enabled, + commonIconToggleButtonContent(checked, checkedContent, uncheckedContent) + ) + +@Composable +actual fun FilledTonalIconToggleButton( + checked: Boolean, + onCheckedChange: (Boolean) -> Unit, + modifier: Modifier, + enabled: Boolean, + uncheckedContent: @Composable () -> Unit, + checkedContent: @Composable (Modifier) -> Unit +) = + com.huanshankeji.compose.material3.FilledTonalIconToggleButton( + checked, + onCheckedChange, + modifier, + enabled, + commonIconToggleButtonContent(checked, checkedContent, uncheckedContent) + ) + +@Composable +actual fun OutlinedIconToggleButton( + checked: Boolean, + onCheckedChange: (Boolean) -> Unit, + modifier: Modifier, + enabled: Boolean, + uncheckedContent: @Composable () -> Unit, + checkedContent: @Composable (Modifier) -> Unit +) = + com.huanshankeji.compose.material3.OutlinedIconToggleButton( + checked, + onCheckedChange, + modifier, + enabled, + commonIconToggleButtonContent(checked, checkedContent, uncheckedContent) + ) diff --git a/compose-multiplatform-material3/src/commonMain/kotlin/com/huanshankeji/compose/material3/IconButton.kt b/compose-multiplatform-material3/src/commonMain/kotlin/com/huanshankeji/compose/material3/IconButton.kt new file mode 100644 index 00000000..6ca804d8 --- /dev/null +++ b/compose-multiplatform-material3/src/commonMain/kotlin/com/huanshankeji/compose/material3/IconButton.kt @@ -0,0 +1,77 @@ +package com.huanshankeji.compose.material3 + +import androidx.compose.runtime.Composable +import com.huanshankeji.compose.ExtRecommendedApi +import com.huanshankeji.compose.ui.Modifier + +@Composable +expect fun IconButton( + onClick: () -> Unit, + modifier: Modifier = Modifier, + enabled: Boolean = true, + content: @Composable () -> Unit +) + +@ExtRecommendedApi +@Composable +expect fun IconToggleButton( + checked: Boolean, + onCheckedChange: (Boolean) -> Unit, + modifier: Modifier = Modifier, + enabled: Boolean = true, + content: @Composable () -> Unit +) + +@Composable +expect fun FilledIconButton( + onClick: () -> Unit, + modifier: Modifier = Modifier, + enabled: Boolean = true, + content: @Composable () -> Unit +) + +@ExtRecommendedApi +@Composable +expect fun FilledIconToggleButton( + checked: Boolean, + onCheckedChange: (Boolean) -> Unit, + modifier: Modifier = Modifier, + enabled: Boolean = true, + content: @Composable () -> Unit +) + +@Composable +expect fun FilledTonalIconButton( + onClick: () -> Unit, + modifier: Modifier = Modifier, + enabled: Boolean = true, + content: @Composable () -> Unit +) + +@ExtRecommendedApi +@Composable +expect fun FilledTonalIconToggleButton( + checked: Boolean, + onCheckedChange: (Boolean) -> Unit, + modifier: Modifier = Modifier, + enabled: Boolean = true, + content: @Composable () -> Unit +) + +@Composable +expect fun OutlinedIconButton( + onClick: () -> Unit, + modifier: Modifier = Modifier, + enabled: Boolean = true, + content: @Composable () -> Unit +) + +@ExtRecommendedApi +@Composable +expect fun OutlinedIconToggleButton( + checked: Boolean, + onCheckedChange: (Boolean) -> Unit, + modifier: Modifier = Modifier, + enabled: Boolean = true, + content: @Composable () -> Unit +) diff --git a/compose-multiplatform-material3/src/commonMain/kotlin/com/huanshankeji/compose/material3/ext/IconButton.kt b/compose-multiplatform-material3/src/commonMain/kotlin/com/huanshankeji/compose/material3/ext/IconButton.kt new file mode 100644 index 00000000..b66ff03a --- /dev/null +++ b/compose-multiplatform-material3/src/commonMain/kotlin/com/huanshankeji/compose/material3/ext/IconButton.kt @@ -0,0 +1,138 @@ +package com.huanshankeji.compose.material3.ext + +import androidx.compose.runtime.Composable +import com.huanshankeji.compose.material.icons.Icon +import com.huanshankeji.compose.material3.Icon +import com.huanshankeji.compose.ui.Modifier + +private fun Icon.toUncheckedIconContent(): @Composable () -> Unit = { + Icon(this, null) +} + +private fun Icon.toCheckedIconContent(): @Composable (Modifier) -> Unit = { modifier -> + Icon(this, null, modifier) +} + +/** + * @param checkedContent the [Modifier] parameter contains the attributes to be set on this icon on JS. You are supposed to pass this [Modifier] to the top-level composable that you invoke inside. + */ +@Composable +expect fun IconToggleButton( + checked: Boolean, + onCheckedChange: (Boolean) -> Unit, + modifier: Modifier = Modifier, + enabled: Boolean = true, + uncheckedContent: @Composable () -> Unit, + checkedContent: @Composable (Modifier) -> Unit +) + +@Composable +fun IconToggleButtonWithMaterialIcons( + checked: Boolean, + onCheckedChange: (Boolean) -> Unit, + modifier: Modifier = Modifier, + enabled: Boolean = true, + uncheckedIcon: Icon, + checkedIcon: Icon +) = + IconToggleButton( + checked, + onCheckedChange, + modifier, + enabled, + uncheckedIcon.toUncheckedIconContent(), + checkedIcon.toCheckedIconContent() + ) + +/** + * @param checkedContent the [Modifier] parameter contains the attributes to be set on this icon on JS. You are supposed to pass this [Modifier] to the top-level composable that you invoke inside. + */ +@Composable +expect fun FilledIconToggleButton( + checked: Boolean, + onCheckedChange: (Boolean) -> Unit, + modifier: Modifier = Modifier, + enabled: Boolean = true, + uncheckedContent: @Composable () -> Unit, + checkedContent: @Composable (Modifier) -> Unit +) + +@Composable +fun FilledIconToggleButtonWithMaterialIcons( + checked: Boolean, + onCheckedChange: (Boolean) -> Unit, + modifier: Modifier = Modifier, + enabled: Boolean = true, + uncheckedIcon: Icon, + checkedIcon: Icon +) = + FilledIconToggleButton( + checked, + onCheckedChange, + modifier, + enabled, + uncheckedIcon.toUncheckedIconContent(), + checkedIcon.toCheckedIconContent() + ) + +/** + * @param checkedContent the [Modifier] parameter contains the attributes to be set on this icon on JS. You are supposed to pass this [Modifier] to the top-level composable that you invoke inside. + */ +@Composable +expect fun FilledTonalIconToggleButton( + checked: Boolean, + onCheckedChange: (Boolean) -> Unit, + modifier: Modifier = Modifier, + enabled: Boolean = true, + uncheckedContent: @Composable () -> Unit, + checkedContent: @Composable (Modifier) -> Unit +) + +@Composable +fun FilledTonalIconToggleButtonWithMaterialIcons( + checked: Boolean, + onCheckedChange: (Boolean) -> Unit, + modifier: Modifier = Modifier, + enabled: Boolean = true, + uncheckedIcon: Icon, + checkedIcon: Icon +) = + FilledTonalIconToggleButton( + checked, + onCheckedChange, + modifier, + enabled, + uncheckedIcon.toUncheckedIconContent(), + checkedIcon.toCheckedIconContent() + ) + +/** + * @param checkedContent the [Modifier] parameter contains the attributes to be set on this icon on JS. You are supposed to pass this [Modifier] to the top-level composable that you invoke inside. + */ +@Composable +expect fun OutlinedIconToggleButton( + checked: Boolean, + onCheckedChange: (Boolean) -> Unit, + modifier: Modifier = Modifier, + enabled: Boolean = true, + uncheckedContent: @Composable () -> Unit, + checkedContent: @Composable (Modifier) -> Unit +) + +@Composable +fun OutlinedIconToggleButtonWithMaterialIcons( + checked: Boolean, + onCheckedChange: (Boolean) -> Unit, + modifier: Modifier = Modifier, + enabled: Boolean = true, + uncheckedIcon: Icon, + checkedIcon: Icon +) = + OutlinedIconToggleButton( + checked, + onCheckedChange, + modifier, + enabled, + uncheckedIcon.toUncheckedIconContent(), + checkedIcon.toCheckedIconContent() + ) diff --git a/compose-multiplatform-material3/src/jsMain/kotlin/com/huanshankeji/compose/material3/IconButton.js.kt b/compose-multiplatform-material3/src/jsMain/kotlin/com/huanshankeji/compose/material3/IconButton.js.kt new file mode 100644 index 00000000..8ba13e95 --- /dev/null +++ b/compose-multiplatform-material3/src/jsMain/kotlin/com/huanshankeji/compose/material3/IconButton.js.kt @@ -0,0 +1,138 @@ +package com.huanshankeji.compose.material3 + +import androidx.compose.runtime.Composable +import com.huanshankeji.compose.html.material3.* +import com.huanshankeji.compose.ui.Modifier +import com.huanshankeji.compose.web.attributes.isFalseOrNull +import com.varabyte.kobweb.compose.ui.toAttrs +import org.jetbrains.compose.web.attributes.AttrsScope +import org.w3c.dom.HTMLElement + +private fun Modifier.toCommonIconButtonAttrs( + onClick: () -> Unit +): AttrsScope.() -> Unit = + platformModifier.toAttrs { + onClick { onClick() } + } + +private fun Modifier.toCommonIconToggleButtonAttrs( + checked: Boolean, onCheckedChange: (Boolean) -> Unit +): AttrsScope.() -> Unit = + toCommonIconButtonAttrs { onCheckedChange(!checked) } + +private fun (@Composable () -> Unit).toCommonIconButtonContent(): @Composable MdIconButtonScope.() -> Unit = + { this@toCommonIconButtonContent() } + +@Composable +actual fun IconButton( + onClick: () -> Unit, + modifier: Modifier, + enabled: Boolean, + content: @Composable () -> Unit +) = + MdIconButton( + enabled.isFalseOrNull(), + attrs = modifier.toCommonIconButtonAttrs(onClick), + content = content.toCommonIconButtonContent() + ) + + +@Composable +actual fun IconToggleButton( + checked: Boolean, + onCheckedChange: (Boolean) -> Unit, + modifier: Modifier, + enabled: Boolean, + content: @Composable () -> Unit +) = + MdIconButton( + enabled.isFalseOrNull(), + /* + // There is no need to use these attributes according to the docs. + toggle = true, + selected = checked, + */ + attrs = modifier.toCommonIconToggleButtonAttrs(checked, onCheckedChange), + content = content.toCommonIconButtonContent() + ) + +@Composable +actual fun FilledIconButton( + onClick: () -> Unit, + modifier: Modifier, + enabled: Boolean, + content: @Composable () -> Unit +) = + MdFilledIconButton( + enabled.isFalseOrNull(), + attrs = modifier.toCommonIconButtonAttrs(onClick), + content = content.toCommonIconButtonContent() + ) + +@Composable +actual fun FilledIconToggleButton( + checked: Boolean, + onCheckedChange: (Boolean) -> Unit, + modifier: Modifier, + enabled: Boolean, + content: @Composable () -> Unit +) = + MdFilledIconButton( + enabled.isFalseOrNull(), + attrs = modifier.toCommonIconToggleButtonAttrs(checked, onCheckedChange), + content = content.toCommonIconButtonContent() + ) + +@Composable +actual fun FilledTonalIconButton( + onClick: () -> Unit, + modifier: Modifier, + enabled: Boolean, + content: @Composable () -> Unit +) = + MdFilledTonalIconButton( + enabled.isFalseOrNull(), + attrs = modifier.toCommonIconButtonAttrs(onClick), + content = content.toCommonIconButtonContent() + ) + +@Composable +actual fun FilledTonalIconToggleButton( + checked: Boolean, + onCheckedChange: (Boolean) -> Unit, + modifier: Modifier, + enabled: Boolean, + content: @Composable () -> Unit +) = + MdFilledTonalIconButton( + enabled.isFalseOrNull(), + attrs = modifier.toCommonIconToggleButtonAttrs(checked, onCheckedChange), + content = content.toCommonIconButtonContent() + ) + +@Composable +actual fun OutlinedIconButton( + onClick: () -> Unit, + modifier: Modifier, + enabled: Boolean, + content: @Composable () -> Unit +) = + MdOutlinedIconButton( + enabled.isFalseOrNull(), + attrs = modifier.toCommonIconButtonAttrs(onClick), + content = content.toCommonIconButtonContent() + ) + +@Composable +actual fun OutlinedIconToggleButton( + checked: Boolean, + onCheckedChange: (Boolean) -> Unit, + modifier: Modifier, + enabled: Boolean, + content: @Composable () -> Unit +) = + MdOutlinedIconButton( + enabled.isFalseOrNull(), + attrs = modifier.toCommonIconToggleButtonAttrs(checked, onCheckedChange), + content = content.toCommonIconButtonContent() + ) diff --git a/compose-multiplatform-material3/src/jsMain/kotlin/com/huanshankeji/compose/material3/ext/IconButton.js.kt b/compose-multiplatform-material3/src/jsMain/kotlin/com/huanshankeji/compose/material3/ext/IconButton.js.kt new file mode 100644 index 00000000..97a6623e --- /dev/null +++ b/compose-multiplatform-material3/src/jsMain/kotlin/com/huanshankeji/compose/material3/ext/IconButton.js.kt @@ -0,0 +1,97 @@ +package com.huanshankeji.compose.material3.ext + +import androidx.compose.runtime.Composable +import com.huanshankeji.compose.html.material3.* +import com.huanshankeji.compose.ui.Modifier +import com.huanshankeji.compose.web.attributes.ext.onInput +import com.huanshankeji.compose.web.attributes.isFalseOrNull +import com.huanshankeji.compose.web.attributes.isTrueOrNull +import com.varabyte.kobweb.compose.ui.attrsModifier +import com.varabyte.kobweb.compose.ui.toAttrs +import org.jetbrains.compose.web.attributes.AttrsScope +import org.w3c.dom.HTMLElement + +private fun Modifier.toCommonIconToggleButtonAttrs( + checked: Boolean, onCheckedChange: (Boolean) -> Unit +): AttrsScope.() -> Unit = + platformModifier.toAttrs { + onInput { onCheckedChange(!checked) } + } + +private fun commonIconToggleButtonContent( + uncheckedContent: @Composable () -> Unit, + checkedContent: @Composable (Modifier) -> Unit +): @Composable MdIconButtonScope.() -> Unit = { + uncheckedContent() + checkedContent(Modifier.platformModify { attrsModifier { slotEqSelected() } }) +} + + +@Composable +actual fun IconToggleButton( + checked: Boolean, + onCheckedChange: (Boolean) -> Unit, + modifier: Modifier, + enabled: Boolean, + uncheckedContent: @Composable () -> Unit, + checkedContent: @Composable (Modifier) -> Unit +) = + MdIconButton( + enabled.isFalseOrNull(), + toggle = true, + selected = checked.isTrueOrNull(), + attrs = modifier.toCommonIconToggleButtonAttrs(checked, onCheckedChange), + content = commonIconToggleButtonContent(uncheckedContent, checkedContent) + ) + + +@Composable +actual fun FilledIconToggleButton( + checked: Boolean, + onCheckedChange: (Boolean) -> Unit, + modifier: Modifier, + enabled: Boolean, + uncheckedContent: @Composable () -> Unit, + checkedContent: @Composable (Modifier) -> Unit +) = + MdFilledIconButton( + enabled.isFalseOrNull(), + toggle = true, + selected = checked.isTrueOrNull(), + attrs = modifier.toCommonIconToggleButtonAttrs(checked, onCheckedChange), + content = commonIconToggleButtonContent(uncheckedContent, checkedContent) + ) + +@Composable +actual fun FilledTonalIconToggleButton( + checked: Boolean, + onCheckedChange: (Boolean) -> Unit, + modifier: Modifier, + enabled: Boolean, + uncheckedContent: @Composable () -> Unit, + checkedContent: @Composable (Modifier) -> Unit +) = + MdFilledTonalIconButton( + enabled.isFalseOrNull(), + toggle = true, + selected = checked.isTrueOrNull(), + attrs = modifier.toCommonIconToggleButtonAttrs(checked, onCheckedChange), + content = commonIconToggleButtonContent(uncheckedContent, checkedContent) + ) + +@Composable +actual fun OutlinedIconToggleButton( + checked: Boolean, + onCheckedChange: (Boolean) -> Unit, + modifier: Modifier, + enabled: Boolean, + uncheckedContent: @Composable () -> Unit, + checkedContent: @Composable (Modifier) -> Unit +) = + MdOutlinedIconButton( + enabled.isFalseOrNull(), + toggle = true, + selected = checked.isTrueOrNull(), + attrs = modifier.toCommonIconToggleButtonAttrs(checked, onCheckedChange), + content = commonIconToggleButtonContent(uncheckedContent, checkedContent) + ) diff --git a/demo/src/commonMain/kotlin/com/huanshankeji/compose/material/demo/Material3.kt b/demo/src/commonMain/kotlin/com/huanshankeji/compose/material/demo/Material3.kt index 0dfb89ab..de17ced1 100644 --- a/demo/src/commonMain/kotlin/com/huanshankeji/compose/material/demo/Material3.kt +++ b/demo/src/commonMain/kotlin/com/huanshankeji/compose/material/demo/Material3.kt @@ -1,6 +1,7 @@ package com.huanshankeji.compose.material.demo import androidx.compose.runtime.* +import com.huanshankeji.compose.ExtRecommendedApi import com.huanshankeji.compose.foundation.layout.Column import com.huanshankeji.compose.foundation.layout.Row import com.huanshankeji.compose.foundation.layout.RowScope @@ -12,8 +13,8 @@ import com.huanshankeji.compose.foundation.text.input.KeyboardType import com.huanshankeji.compose.material.icons.Icons import com.huanshankeji.compose.material.icons.filled.Add import com.huanshankeji.compose.material.icons.filled.Menu -import com.huanshankeji.compose.material3.Checkbox -import com.huanshankeji.compose.material3.Switch +import com.huanshankeji.compose.material.icons.filled.Remove +import com.huanshankeji.compose.material3.* import com.huanshankeji.compose.material3.ext.* import com.huanshankeji.compose.material3.Button as RowScopeButton @@ -38,11 +39,44 @@ fun Material3() { ButtonWithMaterialIcon(onClick, icon = Icons.Default.Add, content = buttonContent) ButtonWithMaterialIcon(onClick, icon = Icons.Default.Add, isTrailingIcon = true, content = buttonContent) } - + val iconButtonContent: @Composable () -> Unit = { + Icon(Icons.Default.Add, null) + } + Row { + IconButton(onClick, content = iconButtonContent) + } + val (checked, onCheckedChange) = remember { mutableStateOf(false) } + val iconToggleButtonContent: @Composable () -> Unit = { + Icon(if (checked) Icons.Default.Add else Icons.Default.Remove, null) + } + @OptIn(ExtRecommendedApi::class) + Row { + IconToggleButton(checked, onCheckedChange, content = iconToggleButtonContent) + FilledIconToggleButton(checked, onCheckedChange, content = iconToggleButtonContent) + FilledTonalIconToggleButton(checked, onCheckedChange, content = iconToggleButtonContent) + OutlinedIconToggleButton(checked, onCheckedChange, content = iconToggleButtonContent) + } + Row { + IconToggleButtonWithMaterialIcons( + checked, onCheckedChange, + uncheckedIcon = Icons.Default.Remove, checkedIcon = Icons.Default.Add + ) + FilledIconToggleButtonWithMaterialIcons( + checked, onCheckedChange, + uncheckedIcon = Icons.Default.Remove, checkedIcon = Icons.Default.Add + ) + FilledTonalIconToggleButtonWithMaterialIcons( + checked, onCheckedChange, + uncheckedIcon = Icons.Default.Remove, checkedIcon = Icons.Default.Add + ) + OutlinedIconToggleButtonWithMaterialIcons( + checked, onCheckedChange, + uncheckedIcon = Icons.Default.Remove, checkedIcon = Icons.Default.Add + ) + } Row { - var checked by remember { mutableStateOf(false) } - Checkbox(checked, { checked = it }) - Switch(checked, { checked = it }) + Checkbox(checked, onCheckedChange) + Switch(checked, onCheckedChange) } var text by remember { mutableStateOf("") } From d187eb85595ef2194e5876c8f96f46cbf2f16b74 Mon Sep 17 00:00:00 2001 From: Shreck Ye Date: Sun, 5 May 2024 10:20:27 +0800 Subject: [PATCH 57/75] Fix the bug that the 2 text fields in the demo are out of sync by setting `HTMLElement.value` explicitly in `DisposableEffect` The corresponding commit: https://github.com/huanshankeji/compose-html-material/commit/5b47847b0bb7c15657dde7a39ed79005dd9fdd04 --- .../compose/material3/ext/TextField.js.kt | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/compose-multiplatform-material3/src/jsMain/kotlin/com/huanshankeji/compose/material3/ext/TextField.js.kt b/compose-multiplatform-material3/src/jsMain/kotlin/com/huanshankeji/compose/material3/ext/TextField.js.kt index 2bef9237..18f41368 100644 --- a/compose-multiplatform-material3/src/jsMain/kotlin/com/huanshankeji/compose/material3/ext/TextField.js.kt +++ b/compose-multiplatform-material3/src/jsMain/kotlin/com/huanshankeji/compose/material3/ext/TextField.js.kt @@ -1,6 +1,7 @@ package com.huanshankeji.compose.material3.ext import androidx.compose.runtime.Composable +import androidx.compose.runtime.DisposableEffect import com.huanshankeji.compose.foundation.text.KeyboardActions import com.huanshankeji.compose.foundation.text.KeyboardOptions import com.huanshankeji.compose.foundation.text.attrsFrom @@ -31,9 +32,16 @@ private fun Modifier.toTextFieldAttrs( } private fun TextFieldContent( + value: String, leadingIcon: @Composable ((Modifier) -> Unit)?, trailingIcon: @Composable ((Modifier) -> Unit)?, ): @Composable MdTextFieldScope.() -> Unit = { + with(elementScope) { + DisposableEffect(value) { + scopeElement.value = value + onDispose {} + } + } leadingIcon?.invoke(PlatformModifier.attrsModifier { slot(MdTextFieldScope.Slot.LeadingIcon) }.toCommonModifier()) trailingIcon?.invoke(PlatformModifier.attrsModifier { slot(MdTextFieldScope.Slot.TrailingIcon) }.toCommonModifier()) } @@ -75,7 +83,7 @@ actual fun TextField( readOnly = readOnly.isTrueOrNull(), attrs = modifier.toTextFieldAttrs(onValueChange, keyboardOptions, keyboardActions), - content = TextFieldContent(leadingIcon, trailingIcon) + content = TextFieldContent(value, leadingIcon, trailingIcon) ) @@ -115,5 +123,5 @@ actual fun OutlinedTextField( readOnly = readOnly.isTrueOrNull(), attrs = modifier.toTextFieldAttrs(onValueChange, keyboardOptions, keyboardActions), - content = TextFieldContent(leadingIcon, trailingIcon) + content = TextFieldContent(value, leadingIcon, trailingIcon) ) From 42eeea4b8c4c3d0b81a5b12d04daeb4592ab84cb Mon Sep 17 00:00:00 2001 From: Shreck Ye Date: Sun, 5 May 2024 22:39:32 +0800 Subject: [PATCH 58/75] Add the floating action button composables and test them in the demo, meanwhile extracting some common functions The corresponding commit: https://github.com/huanshankeji/compose-html-material/commit/8f3692e80a5ac32b6173bbeb16f99bca40ab6cda --- .../foundation/layout/Row.androidxCommon.kt | 7 +- .../compose/foundation/layout/Row.js.kt | 9 ++- .../compose/material/Button.androidxCommon.kt | 21 +++--- .../material3/Button.androidxCommon.kt | 16 ++--- .../FloatingActionButton.androidxCommon.kt | 38 +++++++++++ .../FloatingActionButton.androidxCommon.kt | 45 +++++++++++++ .../material3/ext/TextField.androidxCommon.kt | 2 +- .../compose/material3/FloatingActionButton.kt | 38 +++++++++++ .../compose/material3/ext/Button.kt | 11 ++- .../material3/ext/FloatingActionButton.kt | 67 +++++++++++++++++++ .../compose/material3/ext/Icon.kt | 12 ++++ .../compose/material3/ext/IconButton.kt | 5 +- .../compose/material3/ext/TextField.kt | 13 ++-- .../compose/material3/Button.js.kt | 18 ++--- .../compose/material3/CommonButton.js.kt | 11 +++ .../material3/FloatingActionButton.js.kt | 66 ++++++++++++++++++ .../compose/material3/IconButton.js.kt | 19 ++---- .../material3/ext/FloatingActionButton.js.kt | 44 ++++++++++++ .../compose/material3/ext/IconButton.js.kt | 1 + .../compose/material/demo/Material3.kt | 16 +++++ 20 files changed, 392 insertions(+), 67 deletions(-) create mode 100644 compose-multiplatform-material3/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material3/FloatingActionButton.androidxCommon.kt create mode 100644 compose-multiplatform-material3/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material3/ext/FloatingActionButton.androidxCommon.kt create mode 100644 compose-multiplatform-material3/src/commonMain/kotlin/com/huanshankeji/compose/material3/FloatingActionButton.kt create mode 100644 compose-multiplatform-material3/src/commonMain/kotlin/com/huanshankeji/compose/material3/ext/FloatingActionButton.kt create mode 100644 compose-multiplatform-material3/src/commonMain/kotlin/com/huanshankeji/compose/material3/ext/Icon.kt create mode 100644 compose-multiplatform-material3/src/jsMain/kotlin/com/huanshankeji/compose/material3/CommonButton.js.kt create mode 100644 compose-multiplatform-material3/src/jsMain/kotlin/com/huanshankeji/compose/material3/FloatingActionButton.js.kt create mode 100644 compose-multiplatform-material3/src/jsMain/kotlin/com/huanshankeji/compose/material3/ext/FloatingActionButton.js.kt diff --git a/compose-multiplatform-common/src/androidxCommonMain/kotlin/com/huanshankeji/compose/foundation/layout/Row.androidxCommon.kt b/compose-multiplatform-common/src/androidxCommonMain/kotlin/com/huanshankeji/compose/foundation/layout/Row.androidxCommon.kt index e0c5a769..8e4b8e46 100644 --- a/compose-multiplatform-common/src/androidxCommonMain/kotlin/com/huanshankeji/compose/foundation/layout/Row.androidxCommon.kt +++ b/compose-multiplatform-common/src/androidxCommonMain/kotlin/com/huanshankeji/compose/foundation/layout/Row.androidxCommon.kt @@ -19,7 +19,8 @@ actual fun Row( modifier.platformModifier, horizontalArrangement.platformValue, verticalAlignment.platformHorizontal, - ) { RowScope.Impl(this).content() } + content.toPlatformRowScopeContent(), + ) //@LayoutScopeMarker actual interface RowScope { @@ -38,3 +39,7 @@ actual interface RowScope { actual fun Modifier.align(alignment: Alignment.Vertical): Modifier = with(platformValue) { platformModify { align(alignment.platformHorizontal) } } } + + +fun (@Composable (RowScope.() -> Unit)).toPlatformRowScopeContent(): @Composable PlatformRowScope.() -> Unit = + { RowScope.Impl(this).(this@toPlatformRowScopeContent)() } diff --git a/compose-multiplatform-common/src/jsMain/kotlin/com/huanshankeji/compose/foundation/layout/Row.js.kt b/compose-multiplatform-common/src/jsMain/kotlin/com/huanshankeji/compose/foundation/layout/Row.js.kt index 4e59f3c1..36a61e38 100644 --- a/compose-multiplatform-common/src/jsMain/kotlin/com/huanshankeji/compose/foundation/layout/Row.js.kt +++ b/compose-multiplatform-common/src/jsMain/kotlin/com/huanshankeji/compose/foundation/layout/Row.js.kt @@ -23,8 +23,9 @@ actual fun Row( .sizeFitContent() .then(modifier.platformModifier), horizontalArrangement.platformValue, - verticalAlignment.platformValue - ) { RowScope.Impl(this).content() } + verticalAlignment.platformValue, + content = content.toPlatformRowScopeContent() + ) } @LayoutScopeMarker @@ -44,3 +45,7 @@ actual interface RowScope { actual fun Modifier.align(alignment: Alignment.Vertical): Modifier = with(platformValue) { platformModify { align(alignment.platformValue) } } } + + +fun (@Composable (RowScope.() -> Unit)).toPlatformRowScopeContent(): @Composable PlatformRowScope.() -> Unit = + { RowScope.Impl(this).(this@toPlatformRowScopeContent)() } diff --git a/compose-multiplatform-material/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material/Button.androidxCommon.kt b/compose-multiplatform-material/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material/Button.androidxCommon.kt index ed4b43eb..97e9cb74 100644 --- a/compose-multiplatform-material/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material/Button.androidxCommon.kt +++ b/compose-multiplatform-material/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material/Button.androidxCommon.kt @@ -2,6 +2,7 @@ package com.huanshankeji.compose.material import androidx.compose.runtime.Composable import com.huanshankeji.compose.foundation.layout.RowScope +import com.huanshankeji.compose.foundation.layout.toPlatformRowScopeContent import com.huanshankeji.compose.ui.Modifier @Composable @@ -10,9 +11,7 @@ actual fun Button( modifier: Modifier, content: @Composable RowScope.() -> Unit ) = - androidx.compose.material.Button(onClick, modifier.platformModifier) { - RowScope.Impl(this).content() - } + androidx.compose.material.Button(onClick, modifier.platformModifier, content = content.toPlatformRowScopeContent()) @Composable actual fun OutlinedButton( @@ -20,9 +19,11 @@ actual fun OutlinedButton( modifier: Modifier, content: @Composable RowScope.() -> Unit ) = - androidx.compose.material.OutlinedButton(onClick, modifier.platformModifier) { - RowScope.Impl(this).content() - } + androidx.compose.material.OutlinedButton( + onClick, + modifier.platformModifier, + content = content.toPlatformRowScopeContent() + ) @Composable actual fun TextButton( @@ -30,6 +31,8 @@ actual fun TextButton( modifier: Modifier, content: @Composable RowScope.() -> Unit ) = - androidx.compose.material.TextButton(onClick, modifier.platformModifier) { - RowScope.Impl(this).content() - } + androidx.compose.material.TextButton( + onClick, + modifier.platformModifier, + content = content.toPlatformRowScopeContent() + ) diff --git a/compose-multiplatform-material3/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material3/Button.androidxCommon.kt b/compose-multiplatform-material3/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material3/Button.androidxCommon.kt index 5d481805..13821ed9 100644 --- a/compose-multiplatform-material3/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material3/Button.androidxCommon.kt +++ b/compose-multiplatform-material3/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material3/Button.androidxCommon.kt @@ -2,13 +2,9 @@ package com.huanshankeji.compose.material3 import androidx.compose.runtime.Composable import com.huanshankeji.compose.foundation.layout.RowScope +import com.huanshankeji.compose.foundation.layout.toPlatformRowScopeContent import com.huanshankeji.compose.ui.Modifier -@Composable -private fun (@Composable (RowScope.() -> Unit)).toPlatformContent(): @Composable androidx.compose.foundation.layout.RowScope.() -> Unit = - { RowScope.Impl(this).(this@toPlatformContent)() } - - @Composable actual fun Button( onClick: () -> Unit, @@ -17,7 +13,7 @@ actual fun Button( content: @Composable RowScope.() -> Unit ) = androidx.compose.material3.Button( - onClick, modifier.platformModifier, enabled, content = content.toPlatformContent() + onClick, modifier.platformModifier, enabled, content = content.toPlatformRowScopeContent() ) @Composable @@ -28,7 +24,7 @@ actual fun ElevatedButton( content: @Composable RowScope.() -> Unit ) = androidx.compose.material3.ElevatedButton( - onClick, modifier.platformModifier, enabled, content = content.toPlatformContent() + onClick, modifier.platformModifier, enabled, content = content.toPlatformRowScopeContent() ) @Composable @@ -39,7 +35,7 @@ actual fun FilledTonalButton( content: @Composable RowScope.() -> Unit ) = androidx.compose.material3.FilledTonalButton( - onClick, modifier.platformModifier, enabled, content = content.toPlatformContent() + onClick, modifier.platformModifier, enabled, content = content.toPlatformRowScopeContent() ) @Composable @@ -50,7 +46,7 @@ actual fun OutlinedButton( content: @Composable RowScope.() -> Unit ) = androidx.compose.material3.OutlinedButton( - onClick, modifier.platformModifier, enabled, content = content.toPlatformContent() + onClick, modifier.platformModifier, enabled, content = content.toPlatformRowScopeContent() ) @Composable @@ -61,5 +57,5 @@ actual fun TextButton( content: @Composable RowScope.() -> Unit ) = androidx.compose.material3.TextButton( - onClick, modifier.platformModifier, enabled, content = content.toPlatformContent() + onClick, modifier.platformModifier, enabled, content = content.toPlatformRowScopeContent() ) diff --git a/compose-multiplatform-material3/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material3/FloatingActionButton.androidxCommon.kt b/compose-multiplatform-material3/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material3/FloatingActionButton.androidxCommon.kt new file mode 100644 index 00000000..90e68ca2 --- /dev/null +++ b/compose-multiplatform-material3/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material3/FloatingActionButton.androidxCommon.kt @@ -0,0 +1,38 @@ +package com.huanshankeji.compose.material3 + +import androidx.compose.runtime.Composable +import com.huanshankeji.compose.foundation.layout.RowScope +import com.huanshankeji.compose.foundation.layout.toPlatformRowScopeContent +import com.huanshankeji.compose.ui.Modifier + +@Composable +actual fun FloatingActionButton( + onClick: () -> Unit, + modifier: Modifier, + content: @Composable () -> Unit +) = + androidx.compose.material3.FloatingActionButton(onClick, modifier.platformModifier, content = content) + +@Composable +actual fun SmallFloatingActionButton( + onClick: () -> Unit, + modifier: Modifier, + content: @Composable () -> Unit +) = + androidx.compose.material3.SmallFloatingActionButton(onClick, modifier.platformModifier, content = content) + +@Composable +actual fun LargeFloatingActionButton( + onClick: () -> Unit, + modifier: Modifier, + content: @Composable () -> Unit +) = + androidx.compose.material3.LargeFloatingActionButton(onClick, modifier.platformModifier, content = content) + +@Composable +actual fun ExtendedFloatingActionButton( + onClick: () -> Unit, + modifier: Modifier, + content: @Composable RowScope.() -> Unit +) = + androidx.compose.material3.ExtendedFloatingActionButton(onClick, modifier.platformModifier, content = content.toPlatformRowScopeContent()) diff --git a/compose-multiplatform-material3/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material3/ext/FloatingActionButton.androidxCommon.kt b/compose-multiplatform-material3/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material3/ext/FloatingActionButton.androidxCommon.kt new file mode 100644 index 00000000..56d85627 --- /dev/null +++ b/compose-multiplatform-material3/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material3/ext/FloatingActionButton.androidxCommon.kt @@ -0,0 +1,45 @@ +package com.huanshankeji.compose.material3.ext + +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import com.huanshankeji.compose.ui.Modifier + +private fun (@Composable (Modifier) -> Unit).toContentWithoutModifier(): @Composable () -> Unit = + { this(Modifier) } + + +@Composable +actual fun FloatingActionButton( + onClick: () -> Unit, + modifier: Modifier, + content: @Composable (Modifier) -> Unit +) = + com.huanshankeji.compose.material3.FloatingActionButton(onClick, modifier, content.toContentWithoutModifier()) + +@Composable +actual fun SmallFloatingActionButton( + onClick: () -> Unit, + modifier: Modifier, + content: @Composable (Modifier) -> Unit +) = + com.huanshankeji.compose.material3.SmallFloatingActionButton(onClick, modifier, content.toContentWithoutModifier()) + +@Composable +actual fun LargeFloatingActionButton( + onClick: () -> Unit, + modifier: Modifier, + content: @Composable (Modifier) -> Unit +) = + com.huanshankeji.compose.material3.LargeFloatingActionButton(onClick, modifier, content.toContentWithoutModifier()) + +@Composable +actual fun ExtendedFloatingActionButton( + onClick: () -> Unit, + modifier: Modifier, + label: String, + content: @Composable ((Modifier) -> Unit)? +) = + androidx.compose.material3.ExtendedFloatingActionButton(onClick, modifier.platformModifier) { + content?.invoke(Modifier) + Text(label) + } diff --git a/compose-multiplatform-material3/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material3/ext/TextField.androidxCommon.kt b/compose-multiplatform-material3/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material3/ext/TextField.androidxCommon.kt index 84432b15..fa10e69d 100644 --- a/compose-multiplatform-material3/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material3/ext/TextField.androidxCommon.kt +++ b/compose-multiplatform-material3/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material3/ext/TextField.androidxCommon.kt @@ -8,7 +8,7 @@ import com.huanshankeji.compose.foundation.text.toPlatformValue import com.huanshankeji.compose.ui.Modifier // This function can be moved into a common file. -fun String?.ToNullableTextComposable(): (@Composable () -> Unit)? = +fun String?.ToNullableTextComposable(): @Composable (() -> Unit)? = this?.let { { Text(it) } } private fun (@Composable ((Modifier) -> Unit)?).toContentWithoutModifier(): @Composable (() -> Unit)? = diff --git a/compose-multiplatform-material3/src/commonMain/kotlin/com/huanshankeji/compose/material3/FloatingActionButton.kt b/compose-multiplatform-material3/src/commonMain/kotlin/com/huanshankeji/compose/material3/FloatingActionButton.kt new file mode 100644 index 00000000..b1cc89e3 --- /dev/null +++ b/compose-multiplatform-material3/src/commonMain/kotlin/com/huanshankeji/compose/material3/FloatingActionButton.kt @@ -0,0 +1,38 @@ +package com.huanshankeji.compose.material3 + +import androidx.compose.runtime.Composable +import com.huanshankeji.compose.ExtRecommendedApi +import com.huanshankeji.compose.foundation.layout.RowScope +import com.huanshankeji.compose.ui.Modifier + +@ExtRecommendedApi +@Composable +expect fun FloatingActionButton( + onClick: () -> Unit, + modifier: Modifier = Modifier, + content: @Composable () -> Unit +) + +@ExtRecommendedApi +@Composable +expect fun SmallFloatingActionButton( + onClick: () -> Unit, + modifier: Modifier = Modifier, + content: @Composable () -> Unit +) + +@ExtRecommendedApi +@Composable +expect fun LargeFloatingActionButton( + onClick: () -> Unit, + modifier: Modifier = Modifier, + content: @Composable () -> Unit +) + +@ExtRecommendedApi +@Composable +expect fun ExtendedFloatingActionButton( + onClick: () -> Unit, + modifier: Modifier = Modifier, + content: @Composable RowScope.() -> Unit +) diff --git a/compose-multiplatform-material3/src/commonMain/kotlin/com/huanshankeji/compose/material3/ext/Button.kt b/compose-multiplatform-material3/src/commonMain/kotlin/com/huanshankeji/compose/material3/ext/Button.kt index a49b63bb..e6f44b71 100644 --- a/compose-multiplatform-material3/src/commonMain/kotlin/com/huanshankeji/compose/material3/ext/Button.kt +++ b/compose-multiplatform-material3/src/commonMain/kotlin/com/huanshankeji/compose/material3/ext/Button.kt @@ -2,7 +2,6 @@ package com.huanshankeji.compose.material3.ext import androidx.compose.runtime.Composable import com.huanshankeji.compose.material.icons.Icon -import com.huanshankeji.compose.material3.Icon import com.huanshankeji.compose.ui.Modifier /** @@ -32,7 +31,7 @@ fun ButtonWithMaterialIcon( onClick, modifier, enabled, - icon?.let { { modifier -> Icon(it, null, modifier) } }, + icon.toNullableContentWithModifier(), isTrailingIcon, content ) @@ -74,7 +73,7 @@ fun ElevatedButtonWithMaterialIcon( onClick, modifier, enabled, - icon?.let { { modifier -> Icon(it, null, modifier) } }, + icon.toNullableContentWithModifier(), isTrailingIcon, content ) @@ -102,7 +101,7 @@ fun FilledTonalButtonWithMaterialIcon( onClick, modifier, enabled, - icon?.let { { modifier -> Icon(it, null, modifier) } }, + icon.toNullableContentWithModifier(), isTrailingIcon, content ) @@ -130,7 +129,7 @@ fun OutlinedButtonWithMaterialIcon( onClick, modifier, enabled, - icon?.let { { modifier -> Icon(it, null, modifier) } }, + icon.toNullableContentWithModifier(), isTrailingIcon, content ) @@ -158,7 +157,7 @@ fun TextButtonWithMaterialIcon( onClick, modifier, enabled, - icon?.let { { modifier -> Icon(it, null, modifier) } }, + icon.toNullableContentWithModifier(), isTrailingIcon, content ) diff --git a/compose-multiplatform-material3/src/commonMain/kotlin/com/huanshankeji/compose/material3/ext/FloatingActionButton.kt b/compose-multiplatform-material3/src/commonMain/kotlin/com/huanshankeji/compose/material3/ext/FloatingActionButton.kt new file mode 100644 index 00000000..bc0a174e --- /dev/null +++ b/compose-multiplatform-material3/src/commonMain/kotlin/com/huanshankeji/compose/material3/ext/FloatingActionButton.kt @@ -0,0 +1,67 @@ +package com.huanshankeji.compose.material3.ext + +import androidx.compose.runtime.Composable +import com.huanshankeji.compose.material.icons.Icon +import com.huanshankeji.compose.ui.Modifier + +@Composable +expect fun FloatingActionButton( + onClick: () -> Unit, + modifier: Modifier = Modifier, + content: @Composable (Modifier) -> Unit +) + +@Composable +fun FloatingActionButtonWithMaterialIcon( + onClick: () -> Unit, + modifier: Modifier = Modifier, + icon: Icon +) = + FloatingActionButton(onClick, modifier, icon.toContentWithModifier()) + +@Composable +expect fun SmallFloatingActionButton( + onClick: () -> Unit, + modifier: Modifier = Modifier, + content: @Composable (Modifier) -> Unit +) + +@Composable +fun SmallFloatingActionButtonWithMaterialIcon( + onClick: () -> Unit, + modifier: Modifier = Modifier, + icon: Icon +) = + SmallFloatingActionButton(onClick, modifier, icon.toContentWithModifier()) + +@Composable +expect fun LargeFloatingActionButton( + onClick: () -> Unit, + modifier: Modifier = Modifier, + content: @Composable (Modifier) -> Unit +) + +@Composable +fun LargeFloatingActionButtonWithMaterialIcon( + onClick: () -> Unit, + modifier: Modifier = Modifier, + icon: Icon +) = + LargeFloatingActionButton(onClick, modifier, icon.toContentWithModifier()) + +@Composable +expect fun ExtendedFloatingActionButton( + onClick: () -> Unit, + modifier: Modifier = Modifier, + label: String, + content: @Composable ((Modifier) -> Unit)? +) + +@Composable +fun ExtendedFloatingActionButtonWithMaterialIcon( + onClick: () -> Unit, + modifier: Modifier = Modifier, + label: String, + icon: Icon? +) = + ExtendedFloatingActionButton(onClick, modifier, label, icon.toNullableContentWithModifier()) diff --git a/compose-multiplatform-material3/src/commonMain/kotlin/com/huanshankeji/compose/material3/ext/Icon.kt b/compose-multiplatform-material3/src/commonMain/kotlin/com/huanshankeji/compose/material3/ext/Icon.kt new file mode 100644 index 00000000..b1dfb26a --- /dev/null +++ b/compose-multiplatform-material3/src/commonMain/kotlin/com/huanshankeji/compose/material3/ext/Icon.kt @@ -0,0 +1,12 @@ +package com.huanshankeji.compose.material3.ext + +import androidx.compose.runtime.Composable +import com.huanshankeji.compose.material.icons.Icon +import com.huanshankeji.compose.material3.Icon +import com.huanshankeji.compose.ui.Modifier + +fun Icon.toContentWithModifier(): @Composable (Modifier) -> Unit = + { modifier -> Icon(this, null, modifier) } + +fun Icon?.toNullableContentWithModifier(): @Composable ((Modifier) -> Unit)? = + this?.run { toContentWithModifier() } diff --git a/compose-multiplatform-material3/src/commonMain/kotlin/com/huanshankeji/compose/material3/ext/IconButton.kt b/compose-multiplatform-material3/src/commonMain/kotlin/com/huanshankeji/compose/material3/ext/IconButton.kt index b66ff03a..6ee2d197 100644 --- a/compose-multiplatform-material3/src/commonMain/kotlin/com/huanshankeji/compose/material3/ext/IconButton.kt +++ b/compose-multiplatform-material3/src/commonMain/kotlin/com/huanshankeji/compose/material3/ext/IconButton.kt @@ -9,9 +9,8 @@ private fun Icon.toUncheckedIconContent(): @Composable () -> Unit = { Icon(this, null) } -private fun Icon.toCheckedIconContent(): @Composable (Modifier) -> Unit = { modifier -> - Icon(this, null, modifier) -} +private fun Icon.toCheckedIconContent(): @Composable (Modifier) -> Unit = + toContentWithModifier() /** * @param checkedContent the [Modifier] parameter contains the attributes to be set on this icon on JS. You are supposed to pass this [Modifier] to the top-level composable that you invoke inside. diff --git a/compose-multiplatform-material3/src/commonMain/kotlin/com/huanshankeji/compose/material3/ext/TextField.kt b/compose-multiplatform-material3/src/commonMain/kotlin/com/huanshankeji/compose/material3/ext/TextField.kt index 4650195d..9bd90461 100644 --- a/compose-multiplatform-material3/src/commonMain/kotlin/com/huanshankeji/compose/material3/ext/TextField.kt +++ b/compose-multiplatform-material3/src/commonMain/kotlin/com/huanshankeji/compose/material3/ext/TextField.kt @@ -4,13 +4,8 @@ import androidx.compose.runtime.Composable import com.huanshankeji.compose.foundation.text.KeyboardActions import com.huanshankeji.compose.foundation.text.KeyboardOptions import com.huanshankeji.compose.material.icons.Icon -import com.huanshankeji.compose.material3.Icon import com.huanshankeji.compose.ui.Modifier -private fun Icon?.toIconContentWithModifier(): @Composable ((Modifier) -> Unit)? = - this?.let { { modifier -> Icon(it, null, modifier) } } - - /** * @param leadingIcon the [Modifier] parameter contains the attributes to be set on this icon on JS. You are supposed to pass this [Modifier] to the top-level composable that you invoke inside. * @param trailingIcon ditto. @@ -69,8 +64,8 @@ fun TextFieldWithMaterialIcons( readOnly, label, placeholder, - leadingIcon.toIconContentWithModifier(), - trailingIcon.toIconContentWithModifier(), + leadingIcon.toNullableContentWithModifier(), + trailingIcon.toNullableContentWithModifier(), prefix, suffix, supportingText, @@ -135,8 +130,8 @@ fun OutlinedTextFieldWithMaterialIcons( readOnly, label, placeholder, - leadingIcon.toIconContentWithModifier(), - trailingIcon.toIconContentWithModifier(), + leadingIcon.toNullableContentWithModifier(), + trailingIcon.toNullableContentWithModifier(), prefix, suffix, supportingText, diff --git a/compose-multiplatform-material3/src/jsMain/kotlin/com/huanshankeji/compose/material3/Button.js.kt b/compose-multiplatform-material3/src/jsMain/kotlin/com/huanshankeji/compose/material3/Button.js.kt index dacf5e87..2aa2d171 100644 --- a/compose-multiplatform-material3/src/jsMain/kotlin/com/huanshankeji/compose/material3/Button.js.kt +++ b/compose-multiplatform-material3/src/jsMain/kotlin/com/huanshankeji/compose/material3/Button.js.kt @@ -5,16 +5,8 @@ import com.huanshankeji.compose.foundation.layout.Row import com.huanshankeji.compose.foundation.layout.RowScope import com.huanshankeji.compose.html.material3.* import com.huanshankeji.compose.ui.Modifier -import com.huanshankeji.compose.web.attributes.Attrs import com.huanshankeji.compose.web.attributes.isFalseOrNull import com.huanshankeji.compose.web.attributes.isTrueOrNull -import com.varabyte.kobweb.compose.ui.toAttrs -import org.w3c.dom.HTMLElement - -private fun Modifier.toButtonAttrs(onClick: () -> Unit): Attrs = - platformModifier.toAttrs { - onClick { onClick() } - } @Composable private fun (@Composable (RowScope.() -> Unit)).toMdButtonScopeContent(): @Composable MdButtonScope.() -> Unit = @@ -33,7 +25,7 @@ internal fun CommonButton( MdFilledButton( disabled = enabled.isFalseOrNull(), trailingIcon = isTrailingIcon.isTrueOrNull(), - attrs = modifier.toButtonAttrs(onClick), + attrs = modifier.toCommonButtonAttrs(onClick), content = content ) @@ -57,7 +49,7 @@ internal fun CommonElevatedButton( MdElevatedButton( disabled = enabled.isFalseOrNull(), trailingIcon = isTrailingIcon.isTrueOrNull(), - attrs = modifier.toButtonAttrs(onClick), + attrs = modifier.toCommonButtonAttrs(onClick), content = content ) @@ -81,7 +73,7 @@ internal fun CommonFilledTonalButton( MdFilledTonalButton( disabled = enabled.isFalseOrNull(), trailingIcon = isTrailingIcon.isTrueOrNull(), - attrs = modifier.toButtonAttrs(onClick), + attrs = modifier.toCommonButtonAttrs(onClick), content = content ) @@ -105,7 +97,7 @@ internal fun CommonOutlinedButton( MdOutlinedButton( disabled = enabled.isFalseOrNull(), trailingIcon = isTrailingIcon.isTrueOrNull(), - attrs = modifier.toButtonAttrs(onClick), + attrs = modifier.toCommonButtonAttrs(onClick), content = content ) @@ -129,7 +121,7 @@ internal fun CommonTextButton( MdTextButton( disabled = enabled.isFalseOrNull(), trailingIcon = isTrailingIcon.isTrueOrNull(), - attrs = modifier.toButtonAttrs(onClick), + attrs = modifier.toCommonButtonAttrs(onClick), content = content ) diff --git a/compose-multiplatform-material3/src/jsMain/kotlin/com/huanshankeji/compose/material3/CommonButton.js.kt b/compose-multiplatform-material3/src/jsMain/kotlin/com/huanshankeji/compose/material3/CommonButton.js.kt new file mode 100644 index 00000000..54e66b35 --- /dev/null +++ b/compose-multiplatform-material3/src/jsMain/kotlin/com/huanshankeji/compose/material3/CommonButton.js.kt @@ -0,0 +1,11 @@ +package com.huanshankeji.compose.material3 + +import com.huanshankeji.compose.ui.Modifier +import com.huanshankeji.compose.web.attributes.Attrs +import com.varabyte.kobweb.compose.ui.toAttrs +import org.w3c.dom.HTMLElement + +internal fun Modifier.toCommonButtonAttrs(onClick: () -> Unit): Attrs = + platformModifier.toAttrs { + onClick { onClick() } + } diff --git a/compose-multiplatform-material3/src/jsMain/kotlin/com/huanshankeji/compose/material3/FloatingActionButton.js.kt b/compose-multiplatform-material3/src/jsMain/kotlin/com/huanshankeji/compose/material3/FloatingActionButton.js.kt new file mode 100644 index 00000000..6565312d --- /dev/null +++ b/compose-multiplatform-material3/src/jsMain/kotlin/com/huanshankeji/compose/material3/FloatingActionButton.js.kt @@ -0,0 +1,66 @@ +package com.huanshankeji.compose.material3 + +import androidx.compose.runtime.Composable +import com.huanshankeji.compose.foundation.layout.Box +import com.huanshankeji.compose.foundation.layout.Row +import com.huanshankeji.compose.foundation.layout.RowScope +import com.huanshankeji.compose.html.material3.MdFab +import com.huanshankeji.compose.html.material3.MdFabScope +import com.huanshankeji.compose.ui.Modifier +import com.huanshankeji.compose.ui.toCommonModifier +import com.varabyte.kobweb.compose.ui.attrsModifier +import com.varabyte.kobweb.compose.ui.Modifier as PlatformModifier + +internal val MdFabScope.slotEqIconModifier + get() = PlatformModifier.attrsModifier { slotEqIcon() }.toCommonModifier() + +private fun (@Composable () -> Unit).toBoxedContentWithModifier(): @Composable (Modifier) -> Unit = + { modifier -> + // The content doesn't show without `slot="icon"` set. + // TODO consider using the Kobweb `Box` after resolving the issue whether `fit-content` is needed on the components + Box(modifier) { + this@toBoxedContentWithModifier() + } + } + + +@Composable +actual fun FloatingActionButton( + onClick: () -> Unit, + modifier: Modifier, + content: @Composable () -> Unit +) = + com.huanshankeji.compose.material3.ext.FloatingActionButton( + onClick, modifier, content.toBoxedContentWithModifier() + ) + +@Composable +actual fun SmallFloatingActionButton( + onClick: () -> Unit, + modifier: Modifier, + content: @Composable () -> Unit +) = + com.huanshankeji.compose.material3.ext.SmallFloatingActionButton( + onClick, modifier, content.toBoxedContentWithModifier() + ) + +@Composable +actual fun LargeFloatingActionButton( + onClick: () -> Unit, + modifier: Modifier, + content: @Composable () -> Unit +) = + com.huanshankeji.compose.material3.ext.LargeFloatingActionButton( + onClick, modifier, content.toBoxedContentWithModifier() + ) + +@Composable +actual fun ExtendedFloatingActionButton( + onClick: () -> Unit, + modifier: Modifier, + content: @Composable RowScope.() -> Unit +) = + MdFab(attrs = modifier.toCommonButtonAttrs(onClick)) { + // TODO consider using the Kobweb `Row` after resolving the issue whether `fit-content` is needed on the components + Row(slotEqIconModifier) { content() } + } diff --git a/compose-multiplatform-material3/src/jsMain/kotlin/com/huanshankeji/compose/material3/IconButton.js.kt b/compose-multiplatform-material3/src/jsMain/kotlin/com/huanshankeji/compose/material3/IconButton.js.kt index 8ba13e95..797b9a5b 100644 --- a/compose-multiplatform-material3/src/jsMain/kotlin/com/huanshankeji/compose/material3/IconButton.js.kt +++ b/compose-multiplatform-material3/src/jsMain/kotlin/com/huanshankeji/compose/material3/IconButton.js.kt @@ -4,21 +4,14 @@ import androidx.compose.runtime.Composable import com.huanshankeji.compose.html.material3.* import com.huanshankeji.compose.ui.Modifier import com.huanshankeji.compose.web.attributes.isFalseOrNull -import com.varabyte.kobweb.compose.ui.toAttrs import org.jetbrains.compose.web.attributes.AttrsScope import org.w3c.dom.HTMLElement -private fun Modifier.toCommonIconButtonAttrs( - onClick: () -> Unit -): AttrsScope.() -> Unit = - platformModifier.toAttrs { - onClick { onClick() } - } - private fun Modifier.toCommonIconToggleButtonAttrs( checked: Boolean, onCheckedChange: (Boolean) -> Unit ): AttrsScope.() -> Unit = - toCommonIconButtonAttrs { onCheckedChange(!checked) } + // note `onClick` is used here + toCommonButtonAttrs { onCheckedChange(!checked) } private fun (@Composable () -> Unit).toCommonIconButtonContent(): @Composable MdIconButtonScope.() -> Unit = { this@toCommonIconButtonContent() } @@ -32,7 +25,7 @@ actual fun IconButton( ) = MdIconButton( enabled.isFalseOrNull(), - attrs = modifier.toCommonIconButtonAttrs(onClick), + attrs = modifier.toCommonButtonAttrs(onClick), content = content.toCommonIconButtonContent() ) @@ -65,7 +58,7 @@ actual fun FilledIconButton( ) = MdFilledIconButton( enabled.isFalseOrNull(), - attrs = modifier.toCommonIconButtonAttrs(onClick), + attrs = modifier.toCommonButtonAttrs(onClick), content = content.toCommonIconButtonContent() ) @@ -92,7 +85,7 @@ actual fun FilledTonalIconButton( ) = MdFilledTonalIconButton( enabled.isFalseOrNull(), - attrs = modifier.toCommonIconButtonAttrs(onClick), + attrs = modifier.toCommonButtonAttrs(onClick), content = content.toCommonIconButtonContent() ) @@ -119,7 +112,7 @@ actual fun OutlinedIconButton( ) = MdOutlinedIconButton( enabled.isFalseOrNull(), - attrs = modifier.toCommonIconButtonAttrs(onClick), + attrs = modifier.toCommonButtonAttrs(onClick), content = content.toCommonIconButtonContent() ) diff --git a/compose-multiplatform-material3/src/jsMain/kotlin/com/huanshankeji/compose/material3/ext/FloatingActionButton.js.kt b/compose-multiplatform-material3/src/jsMain/kotlin/com/huanshankeji/compose/material3/ext/FloatingActionButton.js.kt new file mode 100644 index 00000000..6c3c0292 --- /dev/null +++ b/compose-multiplatform-material3/src/jsMain/kotlin/com/huanshankeji/compose/material3/ext/FloatingActionButton.js.kt @@ -0,0 +1,44 @@ +package com.huanshankeji.compose.material3.ext + +import androidx.compose.runtime.Composable +import com.huanshankeji.compose.html.material3.MdFab +import com.huanshankeji.compose.html.material3.MdFabScope +import com.huanshankeji.compose.material3.slotEqIconModifier +import com.huanshankeji.compose.material3.toCommonButtonAttrs +import com.huanshankeji.compose.ui.Modifier + +private fun (@Composable (Modifier) -> Unit).toCommonMdFabContent(): @Composable MdFabScope.() -> Unit = + { this@toCommonMdFabContent(slotEqIconModifier) } + +@Composable +actual fun FloatingActionButton( + onClick: () -> Unit, + modifier: Modifier, + content: @Composable (Modifier) -> Unit +) = + MdFab(attrs = modifier.toCommonButtonAttrs(onClick), content = content.toCommonMdFabContent()) + +@Composable +actual fun SmallFloatingActionButton( + onClick: () -> Unit, + modifier: Modifier, + content: @Composable (Modifier) -> Unit +) = + MdFab(size = "small", attrs = modifier.toCommonButtonAttrs(onClick), content = content.toCommonMdFabContent()) + +@Composable +actual fun LargeFloatingActionButton( + onClick: () -> Unit, + modifier: Modifier, + content: @Composable (Modifier) -> Unit +) = + MdFab(size = "large", attrs = modifier.toCommonButtonAttrs(onClick), content = content.toCommonMdFabContent()) + +@Composable +actual fun ExtendedFloatingActionButton( + onClick: () -> Unit, + modifier: Modifier, + label: String, + content: @Composable ((Modifier) -> Unit)? +) = + MdFab(label = label, attrs = modifier.toCommonButtonAttrs(onClick), content = content?.toCommonMdFabContent()) diff --git a/compose-multiplatform-material3/src/jsMain/kotlin/com/huanshankeji/compose/material3/ext/IconButton.js.kt b/compose-multiplatform-material3/src/jsMain/kotlin/com/huanshankeji/compose/material3/ext/IconButton.js.kt index 97a6623e..f8a7d67e 100644 --- a/compose-multiplatform-material3/src/jsMain/kotlin/com/huanshankeji/compose/material3/ext/IconButton.js.kt +++ b/compose-multiplatform-material3/src/jsMain/kotlin/com/huanshankeji/compose/material3/ext/IconButton.js.kt @@ -15,6 +15,7 @@ private fun Modifier.toCommonIconToggleButtonAttrs( checked: Boolean, onCheckedChange: (Boolean) -> Unit ): AttrsScope.() -> Unit = platformModifier.toAttrs { + // note that `onInput` is used here onInput { onCheckedChange(!checked) } } diff --git a/demo/src/commonMain/kotlin/com/huanshankeji/compose/material/demo/Material3.kt b/demo/src/commonMain/kotlin/com/huanshankeji/compose/material/demo/Material3.kt index de17ced1..25473cd8 100644 --- a/demo/src/commonMain/kotlin/com/huanshankeji/compose/material/demo/Material3.kt +++ b/demo/src/commonMain/kotlin/com/huanshankeji/compose/material/demo/Material3.kt @@ -74,6 +74,22 @@ fun Material3() { uncheckedIcon = Icons.Default.Remove, checkedIcon = Icons.Default.Add ) } + @OptIn(ExtRecommendedApi::class) + Row { + FloatingActionButton(onClick, content = iconButtonContent) + SmallFloatingActionButton(onClick, content = iconButtonContent) + LargeFloatingActionButton(onClick, content = iconButtonContent) + ExtendedFloatingActionButton(onClick) { + iconButtonContent() + Text("Add") + } + } + Row { + FloatingActionButtonWithMaterialIcon(onClick, icon = Icons.Default.Add) + SmallFloatingActionButtonWithMaterialIcon(onClick, icon = Icons.Default.Add) + LargeFloatingActionButtonWithMaterialIcon(onClick, icon = Icons.Default.Add) + ExtendedFloatingActionButtonWithMaterialIcon(onClick, label = "Add", icon = Icons.Default.Add) + } Row { Checkbox(checked, onCheckedChange) Switch(checked, onCheckedChange) From 0f270f10cd5b2e54a44ce5e0badc5ffad904127c Mon Sep 17 00:00:00 2001 From: Shreck Ye Date: Mon, 6 May 2024 06:22:41 +0800 Subject: [PATCH 59/75] Make the color scheme change when toggling the non-`ext` toggle buttons on JS to be consistent with those in `androidx.compose` --- .../compose/material3/IconButton.js.kt | 35 ++++++++++++++----- .../compose/material3/ext/IconButton.js.kt | 17 ++------- 2 files changed, 29 insertions(+), 23 deletions(-) diff --git a/compose-multiplatform-material3/src/jsMain/kotlin/com/huanshankeji/compose/material3/IconButton.js.kt b/compose-multiplatform-material3/src/jsMain/kotlin/com/huanshankeji/compose/material3/IconButton.js.kt index 797b9a5b..4dc13be9 100644 --- a/compose-multiplatform-material3/src/jsMain/kotlin/com/huanshankeji/compose/material3/IconButton.js.kt +++ b/compose-multiplatform-material3/src/jsMain/kotlin/com/huanshankeji/compose/material3/IconButton.js.kt @@ -1,20 +1,34 @@ package com.huanshankeji.compose.material3 import androidx.compose.runtime.Composable +import com.huanshankeji.compose.foundation.layout.Box import com.huanshankeji.compose.html.material3.* import com.huanshankeji.compose.ui.Modifier +import com.huanshankeji.compose.ui.toCommonModifier +import com.huanshankeji.compose.web.attributes.ext.onInput import com.huanshankeji.compose.web.attributes.isFalseOrNull +import com.huanshankeji.compose.web.attributes.isTrueOrNull +import com.varabyte.kobweb.compose.ui.attrsModifier +import com.varabyte.kobweb.compose.ui.toAttrs import org.jetbrains.compose.web.attributes.AttrsScope import org.w3c.dom.HTMLElement +import com.varabyte.kobweb.compose.ui.Modifier as PlatformModifier -private fun Modifier.toCommonIconToggleButtonAttrs( +internal fun Modifier.toCommonIconToggleButtonAttrs( checked: Boolean, onCheckedChange: (Boolean) -> Unit ): AttrsScope.() -> Unit = - // note `onClick` is used here - toCommonButtonAttrs { onCheckedChange(!checked) } + platformModifier.toAttrs { + // note that `onInput` is used here + onInput { onCheckedChange(!checked) } + } -private fun (@Composable () -> Unit).toCommonIconButtonContent(): @Composable MdIconButtonScope.() -> Unit = - { this@toCommonIconButtonContent() } +internal fun MdIconButtonScope.slotEqSelectedModifier() = + PlatformModifier.attrsModifier { slotEqSelected() }.toCommonModifier() + +private fun (@Composable () -> Unit).toCommonIconButtonContent(): @Composable MdIconButtonScope.() -> Unit = { + Box { this@toCommonIconButtonContent() } + Box(slotEqSelectedModifier()) { this@toCommonIconButtonContent() } +} @Composable actual fun IconButton( @@ -40,11 +54,8 @@ actual fun IconToggleButton( ) = MdIconButton( enabled.isFalseOrNull(), - /* - // There is no need to use these attributes according to the docs. toggle = true, - selected = checked, - */ + selected = checked.isTrueOrNull(), attrs = modifier.toCommonIconToggleButtonAttrs(checked, onCheckedChange), content = content.toCommonIconButtonContent() ) @@ -72,6 +83,8 @@ actual fun FilledIconToggleButton( ) = MdFilledIconButton( enabled.isFalseOrNull(), + toggle = true, + selected = checked.isTrueOrNull(), attrs = modifier.toCommonIconToggleButtonAttrs(checked, onCheckedChange), content = content.toCommonIconButtonContent() ) @@ -99,6 +112,8 @@ actual fun FilledTonalIconToggleButton( ) = MdFilledTonalIconButton( enabled.isFalseOrNull(), + toggle = true, + selected = checked.isTrueOrNull(), attrs = modifier.toCommonIconToggleButtonAttrs(checked, onCheckedChange), content = content.toCommonIconButtonContent() ) @@ -126,6 +141,8 @@ actual fun OutlinedIconToggleButton( ) = MdOutlinedIconButton( enabled.isFalseOrNull(), + toggle = true, + selected = checked.isTrueOrNull(), attrs = modifier.toCommonIconToggleButtonAttrs(checked, onCheckedChange), content = content.toCommonIconButtonContent() ) diff --git a/compose-multiplatform-material3/src/jsMain/kotlin/com/huanshankeji/compose/material3/ext/IconButton.js.kt b/compose-multiplatform-material3/src/jsMain/kotlin/com/huanshankeji/compose/material3/ext/IconButton.js.kt index f8a7d67e..75fefad4 100644 --- a/compose-multiplatform-material3/src/jsMain/kotlin/com/huanshankeji/compose/material3/ext/IconButton.js.kt +++ b/compose-multiplatform-material3/src/jsMain/kotlin/com/huanshankeji/compose/material3/ext/IconButton.js.kt @@ -2,29 +2,18 @@ package com.huanshankeji.compose.material3.ext import androidx.compose.runtime.Composable import com.huanshankeji.compose.html.material3.* +import com.huanshankeji.compose.material3.slotEqSelectedModifier +import com.huanshankeji.compose.material3.toCommonIconToggleButtonAttrs import com.huanshankeji.compose.ui.Modifier -import com.huanshankeji.compose.web.attributes.ext.onInput import com.huanshankeji.compose.web.attributes.isFalseOrNull import com.huanshankeji.compose.web.attributes.isTrueOrNull -import com.varabyte.kobweb.compose.ui.attrsModifier -import com.varabyte.kobweb.compose.ui.toAttrs -import org.jetbrains.compose.web.attributes.AttrsScope -import org.w3c.dom.HTMLElement - -private fun Modifier.toCommonIconToggleButtonAttrs( - checked: Boolean, onCheckedChange: (Boolean) -> Unit -): AttrsScope.() -> Unit = - platformModifier.toAttrs { - // note that `onInput` is used here - onInput { onCheckedChange(!checked) } - } private fun commonIconToggleButtonContent( uncheckedContent: @Composable () -> Unit, checkedContent: @Composable (Modifier) -> Unit ): @Composable MdIconButtonScope.() -> Unit = { uncheckedContent() - checkedContent(Modifier.platformModify { attrsModifier { slotEqSelected() } }) + checkedContent(slotEqSelectedModifier()) } From b5d2904cc74efdcc930ba6efaef94a4e594ff918 Mon Sep 17 00:00:00 2001 From: Shreck Ye Date: Mon, 6 May 2024 06:44:45 +0800 Subject: [PATCH 60/75] Show all types of icon buttons in the demo --- .../kotlin/com/huanshankeji/compose/material/demo/Material3.kt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/demo/src/commonMain/kotlin/com/huanshankeji/compose/material/demo/Material3.kt b/demo/src/commonMain/kotlin/com/huanshankeji/compose/material/demo/Material3.kt index 25473cd8..a7cc1075 100644 --- a/demo/src/commonMain/kotlin/com/huanshankeji/compose/material/demo/Material3.kt +++ b/demo/src/commonMain/kotlin/com/huanshankeji/compose/material/demo/Material3.kt @@ -44,6 +44,9 @@ fun Material3() { } Row { IconButton(onClick, content = iconButtonContent) + FilledIconButton(onClick, content = iconButtonContent) + FilledTonalIconButton(onClick, content = iconButtonContent) + OutlinedIconButton(onClick, content = iconButtonContent) } val (checked, onCheckedChange) = remember { mutableStateOf(false) } val iconToggleButtonContent: @Composable () -> Unit = { From 46e06709f6e074c039bb646e4b310bb908f80a9d Mon Sep 17 00:00:00 2001 From: Shreck Ye Date: Tue, 7 May 2024 12:13:37 +0800 Subject: [PATCH 61/75] Refactor lazy DSLs adding `LazyColumn` and `LazyRow` in the `foundation` package, and add the Material 3 `List` composable `LazyColumn` and `LazyRow` behave more like `Column` and `Row` visually instead of `MDCList`, and are therefore added to the `foundation` package. A `DeferredComposableRunner` for composing lazy DSL `content` on JS is extracted. The Material 2 `LazyColumn`/`List` should be refactored too. The corresponding commit: https://github.com/huanshankeji/compose-html-material/commit/8746b5742c3c70785e4bfcbbbeff4e3a812f2831 --- .../compose/Content.androidxCommon.kt | 10 ++ .../foundation/lazy/LazyDsl.androidxCommon.kt | 57 ++++++++ .../lazy/LazyItemScope.androidxCommon.kt | 30 +++++ .../compose/foundation/lazy/LazyDsl.kt | 123 ++++++++++++++++++ .../compose/foundation/lazy/LazyItemScope.kt | 37 ++++++ .../runtime/DeferredComposableRunner.kt | 20 +++ .../compose/foundation/lazy/LazyDsl.js.kt | 84 ++++++++++++ .../foundation/lazy/LazyItemScope.js.kt | 35 +++++ .../lazy/ext/LazyDsl.androidxCommon.kt | 8 +- .../compose/material/lazy/ext/LazyDsl.kt | 12 +- .../compose/material/lazy/ext/LazyDsl.js.kt | 36 +++-- .../FloatingActionButton.androidxCommon.kt | 5 +- .../material3/lazy/ext/List.androidxCommon.kt | 77 +++++++++++ .../compose/material3/ext/Icon.kt | 2 +- .../compose/material3/ext/Text.kt | 7 + .../compose/material3/lazy/ext/List.kt | 67 ++++++++++ .../compose/material3/lazy/ext/List.js.kt | 97 ++++++++++++++ .../huanshankeji/compose/material/demo/App.kt | 24 ++-- .../compose/material/demo/Common.kt | 68 ++++++++++ .../compose/material/demo/Material2.kt | 39 +----- .../compose/material/demo/Material3.kt | 19 +++ 21 files changed, 772 insertions(+), 85 deletions(-) create mode 100644 compose-multiplatform-common/src/androidxCommonMain/kotlin/com/huanshankeji/compose/Content.androidxCommon.kt create mode 100644 compose-multiplatform-common/src/androidxCommonMain/kotlin/com/huanshankeji/compose/foundation/lazy/LazyDsl.androidxCommon.kt create mode 100644 compose-multiplatform-common/src/androidxCommonMain/kotlin/com/huanshankeji/compose/foundation/lazy/LazyItemScope.androidxCommon.kt create mode 100644 compose-multiplatform-common/src/commonMain/kotlin/com/huanshankeji/compose/foundation/lazy/LazyDsl.kt create mode 100644 compose-multiplatform-common/src/commonMain/kotlin/com/huanshankeji/compose/foundation/lazy/LazyItemScope.kt create mode 100644 compose-multiplatform-common/src/commonMain/kotlin/com/huanshankeji/compose/runtime/DeferredComposableRunner.kt create mode 100644 compose-multiplatform-common/src/jsMain/kotlin/com/huanshankeji/compose/foundation/lazy/LazyDsl.js.kt create mode 100644 compose-multiplatform-common/src/jsMain/kotlin/com/huanshankeji/compose/foundation/lazy/LazyItemScope.js.kt create mode 100644 compose-multiplatform-material3/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material3/lazy/ext/List.androidxCommon.kt create mode 100644 compose-multiplatform-material3/src/commonMain/kotlin/com/huanshankeji/compose/material3/lazy/ext/List.kt create mode 100644 compose-multiplatform-material3/src/jsMain/kotlin/com/huanshankeji/compose/material3/lazy/ext/List.js.kt create mode 100644 demo/src/commonMain/kotlin/com/huanshankeji/compose/material/demo/Common.kt diff --git a/compose-multiplatform-common/src/androidxCommonMain/kotlin/com/huanshankeji/compose/Content.androidxCommon.kt b/compose-multiplatform-common/src/androidxCommonMain/kotlin/com/huanshankeji/compose/Content.androidxCommon.kt new file mode 100644 index 00000000..ef41ed0c --- /dev/null +++ b/compose-multiplatform-common/src/androidxCommonMain/kotlin/com/huanshankeji/compose/Content.androidxCommon.kt @@ -0,0 +1,10 @@ +package com.huanshankeji.compose + +import androidx.compose.runtime.Composable +import com.huanshankeji.compose.ui.Modifier + +fun (@Composable (Modifier) -> Unit).toContentWithoutModifier(): @Composable () -> Unit = + { this(Modifier) } + +fun (@Composable (Modifier) -> Unit)?.toNullableContentWithoutModifier(): @Composable (() -> Unit)? = + this?.toContentWithoutModifier() diff --git a/compose-multiplatform-common/src/androidxCommonMain/kotlin/com/huanshankeji/compose/foundation/lazy/LazyDsl.androidxCommon.kt b/compose-multiplatform-common/src/androidxCommonMain/kotlin/com/huanshankeji/compose/foundation/lazy/LazyDsl.androidxCommon.kt new file mode 100644 index 00000000..0047c1ba --- /dev/null +++ b/compose-multiplatform-common/src/androidxCommonMain/kotlin/com/huanshankeji/compose/foundation/lazy/LazyDsl.androidxCommon.kt @@ -0,0 +1,57 @@ +package com.huanshankeji.compose.foundation.lazy + +import androidx.compose.foundation.lazy.LazyScopeMarker +import androidx.compose.runtime.Composable +import com.huanshankeji.compose.foundation.layout.Arrangement +import com.huanshankeji.compose.ui.Alignment +import com.huanshankeji.compose.ui.Modifier + +@LazyScopeMarker +//@JvmDefaultWithCompatibility +actual class LazyListScope(val platformValue: androidx.compose.foundation.lazy.LazyListScope) { + actual fun item( + key: Any?, + contentType: Any?, + content: @Composable LazyItemScope.() -> Unit + ) = + platformValue.item(key, contentType) { LazyItemScope(this).content() } + + + actual fun items( + count: Int, + key: ((index: Int) -> Any)?, + contentType: (index: Int) -> Any?, + itemContent: @Composable LazyItemScope.(index: Int) -> Unit + ) = + platformValue.items(count, key, contentType) { index -> LazyItemScope(this).itemContent(index) } +} + +@Composable +actual fun LazyRow( + modifier: Modifier, + reverseLayout: Boolean, + horizontalArrangement: Arrangement.Horizontal, + verticalAlignment: Alignment.Vertical, + content: LazyListScope.() -> Unit +) = + androidx.compose.foundation.lazy.LazyRow( + modifier.platformModifier, + reverseLayout = reverseLayout, + horizontalArrangement = horizontalArrangement.platformValue, + verticalAlignment = verticalAlignment.platformHorizontal + ) { LazyListScope(this).content() } + +@Composable +actual fun LazyColumn( + modifier: Modifier, + reverseLayout: Boolean, + verticalArrangement: Arrangement.Vertical, + horizontalAlignment: Alignment.Horizontal, + content: LazyListScope.() -> Unit +) = + androidx.compose.foundation.lazy.LazyColumn( + modifier.platformModifier, + reverseLayout = reverseLayout, + verticalArrangement = verticalArrangement.platformValue, + horizontalAlignment = horizontalAlignment.platformHorizontal + ) { LazyListScope(this).content() } diff --git a/compose-multiplatform-common/src/androidxCommonMain/kotlin/com/huanshankeji/compose/foundation/lazy/LazyItemScope.androidxCommon.kt b/compose-multiplatform-common/src/androidxCommonMain/kotlin/com/huanshankeji/compose/foundation/lazy/LazyItemScope.androidxCommon.kt new file mode 100644 index 00000000..c6c00935 --- /dev/null +++ b/compose-multiplatform-common/src/androidxCommonMain/kotlin/com/huanshankeji/compose/foundation/lazy/LazyItemScope.androidxCommon.kt @@ -0,0 +1,30 @@ +package com.huanshankeji.compose.foundation.lazy + +import androidx.annotation.FloatRange +import androidx.compose.foundation.lazy.LazyScopeMarker +import androidx.compose.runtime.Stable +import com.huanshankeji.compose.ui.Modifier +import androidx.compose.foundation.lazy.LazyItemScope as PlatformLazyItemScope + +@Stable +@LazyScopeMarker +//@JvmDefaultWithCompatibility +actual class LazyItemScope(val platformValue: PlatformLazyItemScope) { + actual fun Modifier.fillParentMaxSize( + @FloatRange(from = 0.0, to = 1.0) + fraction: Float + ): Modifier = + platformModify { with(platformValue) { fillParentMaxSize(fraction) } } + + actual fun Modifier.fillParentMaxWidth( + @FloatRange(from = 0.0, to = 1.0) + fraction: Float + ): Modifier = + platformModify { with(platformValue) { fillParentMaxWidth(fraction) } } + + actual fun Modifier.fillParentMaxHeight( + @FloatRange(from = 0.0, to = 1.0) + fraction: Float + ): Modifier = + platformModify { with(platformValue) { fillParentMaxHeight(fraction) } } +} \ No newline at end of file diff --git a/compose-multiplatform-common/src/commonMain/kotlin/com/huanshankeji/compose/foundation/lazy/LazyDsl.kt b/compose-multiplatform-common/src/commonMain/kotlin/com/huanshankeji/compose/foundation/lazy/LazyDsl.kt new file mode 100644 index 00000000..fddc0ad0 --- /dev/null +++ b/compose-multiplatform-common/src/commonMain/kotlin/com/huanshankeji/compose/foundation/lazy/LazyDsl.kt @@ -0,0 +1,123 @@ +package com.huanshankeji.compose.foundation.lazy + +import androidx.compose.runtime.Composable +import com.huanshankeji.compose.foundation.layout.Arrangement +import com.huanshankeji.compose.ui.Alignment +import com.huanshankeji.compose.ui.Modifier + +// copied and adapted from `LazyDsl.kt` in `androidx.compose.foundation.lazy` + + +/* +@LazyScopeMarker +@JvmDefaultWithCompatibility +*/ +expect class LazyListScope { + fun item( + key: Any? = null, + contentType: Any? = null, + content: @Composable LazyItemScope.() -> Unit + ) + + fun items( + count: Int, + key: ((index: Int) -> Any)? = null, + contentType: (index: Int) -> Any? = { null }, + itemContent: @Composable LazyItemScope.(index: Int) -> Unit + ) + + /* + @ExperimentalFoundationApi + fun stickyHeader( + key: Any? = null, + contentType: Any? = null, + content: @Composable LazyItemScope.() -> Unit + ) + */ +} + +inline fun LazyListScope.items( + items: List, + noinline key: ((item: T) -> Any)? = null, + noinline contentType: (item: T) -> Any? = { null }, + crossinline itemContent: @Composable LazyItemScope.(item: T) -> Unit +) = items( + count = items.size, + key = if (key != null) { index: Int -> key(items[index]) } else null, + contentType = { index: Int -> contentType(items[index]) } +) { + itemContent(items[it]) +} + +inline fun LazyListScope.itemsIndexed( + items: List, + noinline key: ((index: Int, item: T) -> Any)? = null, + crossinline contentType: (index: Int, item: T) -> Any? = { _, _ -> null }, + crossinline itemContent: @Composable LazyItemScope.(index: Int, item: T) -> Unit +) = items( + count = items.size, + key = if (key != null) { index: Int -> key(index, items[index]) } else null, + contentType = { index -> contentType(index, items[index]) } +) { + itemContent(it, items[it]) +} + +inline fun LazyListScope.items( + items: Array, + noinline key: ((item: T) -> Any)? = null, + noinline contentType: (item: T) -> Any? = { null }, + crossinline itemContent: @Composable LazyItemScope.(item: T) -> Unit +) = items( + count = items.size, + key = if (key != null) { index: Int -> key(items[index]) } else null, + contentType = { index: Int -> contentType(items[index]) } +) { + itemContent(items[it]) +} + +inline fun LazyListScope.itemsIndexed( + items: Array, + noinline key: ((index: Int, item: T) -> Any)? = null, + crossinline contentType: (index: Int, item: T) -> Any? = { _, _ -> null }, + crossinline itemContent: @Composable LazyItemScope.(index: Int, item: T) -> Unit +) = items( + count = items.size, + key = if (key != null) { index: Int -> key(index, items[index]) } else null, + contentType = { index -> contentType(index, items[index]) } +) { + itemContent(it, items[it]) +} + +/** + * No need to be lazy on JS. + */ +@Composable +expect fun LazyRow( + modifier: Modifier = Modifier, + //state: LazyListState = rememberLazyListState(), + //contentPadding: PaddingValues = PaddingValues(0.dp), + reverseLayout: Boolean = false, + horizontalArrangement: Arrangement.Horizontal = + if (!reverseLayout) Arrangement.Start else Arrangement.End, + verticalAlignment: Alignment.Vertical = Alignment.Top, + //flingBehavior: FlingBehavior = ScrollableDefaults.flingBehavior(), + //userScrollEnabled: Boolean = true, // This property works together with `state`. + content: LazyListScope.() -> Unit +) + +/** + * No need to be lazy on JS. + */ +@Composable +expect fun LazyColumn( + modifier: Modifier = Modifier, + //state: LazyListState = rememberLazyListState(), + //contentPadding: PaddingValues = PaddingValues(0.dp), + reverseLayout: Boolean = false, + verticalArrangement: Arrangement.Vertical = + if (!reverseLayout) Arrangement.Top else Arrangement.Bottom, + horizontalAlignment: Alignment.Horizontal = Alignment.Start, + //flingBehavior: FlingBehavior = ScrollableDefaults.flingBehavior(), + //userScrollEnabled: Boolean = true, // This property works together with `state`. + content: LazyListScope.() -> Unit +) diff --git a/compose-multiplatform-common/src/commonMain/kotlin/com/huanshankeji/compose/foundation/lazy/LazyItemScope.kt b/compose-multiplatform-common/src/commonMain/kotlin/com/huanshankeji/compose/foundation/lazy/LazyItemScope.kt new file mode 100644 index 00000000..cb641a4a --- /dev/null +++ b/compose-multiplatform-common/src/commonMain/kotlin/com/huanshankeji/compose/foundation/lazy/LazyItemScope.kt @@ -0,0 +1,37 @@ +package com.huanshankeji.compose.foundation.lazy + +import androidx.annotation.FloatRange +import androidx.compose.runtime.Stable +import com.huanshankeji.compose.ui.Modifier + +@Stable +/* +@LazyScopeMarker +@JvmDefaultWithCompatibility +*/ +expect class LazyItemScope { + fun Modifier.fillParentMaxSize( + @FloatRange(from = 0.0, to = 1.0) + fraction: Float = 1f + ): Modifier + + fun Modifier.fillParentMaxWidth( + @FloatRange(from = 0.0, to = 1.0) + fraction: Float = 1f + ): Modifier + + fun Modifier.fillParentMaxHeight( + @FloatRange(from = 0.0, to = 1.0) + fraction: Float = 1f + ): Modifier + + /* + @ExperimentalFoundationApi + fun Modifier.animateItemPlacement( + animationSpec: FiniteAnimationSpec = spring( + stiffness = Spring.StiffnessMediumLow, + visibilityThreshold = androidx.compose.ui.unit.IntOffset.VisibilityThreshold + ) + ): Modifier + */ +} diff --git a/compose-multiplatform-common/src/commonMain/kotlin/com/huanshankeji/compose/runtime/DeferredComposableRunner.kt b/compose-multiplatform-common/src/commonMain/kotlin/com/huanshankeji/compose/runtime/DeferredComposableRunner.kt new file mode 100644 index 00000000..f82579ce --- /dev/null +++ b/compose-multiplatform-common/src/commonMain/kotlin/com/huanshankeji/compose/runtime/DeferredComposableRunner.kt @@ -0,0 +1,20 @@ +package com.huanshankeji.compose.runtime + +import androidx.compose.runtime.Composable + +class DeferredComposableRunner { + private var composables: MutableList<@Composable () -> Unit>? = null + fun addComposable(composable: @Composable () -> Unit) { + composables!!.add(composable) + } + + /** Add the composable functions with the non-composable functions and then invoke them. */ + @Composable + fun ComposableRun(content: () -> Unit) { + composables = mutableListOf() + content() + for (composable in composables!!) + composable() + composables = null + } +} diff --git a/compose-multiplatform-common/src/jsMain/kotlin/com/huanshankeji/compose/foundation/lazy/LazyDsl.js.kt b/compose-multiplatform-common/src/jsMain/kotlin/com/huanshankeji/compose/foundation/lazy/LazyDsl.js.kt new file mode 100644 index 00000000..71047818 --- /dev/null +++ b/compose-multiplatform-common/src/jsMain/kotlin/com/huanshankeji/compose/foundation/lazy/LazyDsl.js.kt @@ -0,0 +1,84 @@ +package com.huanshankeji.compose.foundation.lazy + +import androidx.compose.runtime.Composable +import com.huanshankeji.compose.foundation.layout.Arrangement +import com.huanshankeji.compose.foundation.layout.Column +import com.huanshankeji.compose.foundation.layout.Row +import com.huanshankeji.compose.runtime.DeferredComposableRunner +import com.huanshankeji.compose.ui.Alignment +import com.huanshankeji.compose.ui.Modifier +import com.varabyte.kobweb.compose.css.Overflow +import com.varabyte.kobweb.compose.css.overflowX +import com.varabyte.kobweb.compose.css.overflowY +import com.varabyte.kobweb.compose.ui.styleModifier +import org.jetbrains.compose.web.css.StyleScope + +/* +@LazyScopeMarker +@JvmDefaultWithCompatibility +*/ +actual class LazyListScope { + private val deferredComposableRunner = DeferredComposableRunner() + + private fun addComposable(composable: @Composable () -> Unit) = + deferredComposableRunner.addComposable(composable) + + @Composable + internal fun ComposableRun(content: LazyListScope.() -> Unit) = + deferredComposableRunner.ComposableRun { content() } + + actual fun item( + key: Any?, + contentType: Any?, + content: @Composable LazyItemScope.() -> Unit + ) = + addComposable { LazyItemScope.content() } + + actual fun items( + count: Int, + key: ((index: Int) -> Any)?, + contentType: (index: Int) -> Any?, + itemContent: @Composable LazyItemScope.(index: Int) -> Unit + ) = + addComposable { + repeat(count) { index -> + LazyItemScope.itemContent(index) + } + } +} + +@Composable +actual fun LazyRow( + modifier: Modifier, + reverseLayout: Boolean, // This parameter is not used yet but affects the arrangement in the default argument of the corresponding `expect` function. + horizontalArrangement: Arrangement.Horizontal, + verticalAlignment: Alignment.Vertical, + content: LazyListScope.() -> Unit +) = + Row(modifier.platformModify { + styleModifier { rowOverflow() } + }, horizontalArrangement, verticalAlignment) { + LazyListScope().ComposableRun(content) + } + +@Composable +actual fun LazyColumn( + modifier: Modifier, + reverseLayout: Boolean, // This parameter is not used yet but affects the arrangement in the default argument of the corresponding `expect` function. + verticalArrangement: Arrangement.Vertical, + horizontalAlignment: Alignment.Horizontal, + content: LazyListScope.() -> Unit +) = + Column(modifier.platformModify { + styleModifier { columnOverflow() } + }, verticalArrangement, horizontalAlignment) { + LazyListScope().ComposableRun(content) + } + + +fun StyleScope.rowOverflow() = + overflowX(Overflow.Auto) + +fun StyleScope.columnOverflow() = + //overflowY(Overflow.Scroll) + overflowY(Overflow.Auto) diff --git a/compose-multiplatform-common/src/jsMain/kotlin/com/huanshankeji/compose/foundation/lazy/LazyItemScope.js.kt b/compose-multiplatform-common/src/jsMain/kotlin/com/huanshankeji/compose/foundation/lazy/LazyItemScope.js.kt new file mode 100644 index 00000000..945d09ee --- /dev/null +++ b/compose-multiplatform-common/src/jsMain/kotlin/com/huanshankeji/compose/foundation/lazy/LazyItemScope.js.kt @@ -0,0 +1,35 @@ +package com.huanshankeji.compose.foundation.lazy + +import androidx.annotation.FloatRange +import androidx.compose.runtime.Stable +import com.huanshankeji.compose.layout.fillMaxHeight +import com.huanshankeji.compose.layout.fillMaxSize +import com.huanshankeji.compose.layout.fillMaxWidth +import com.huanshankeji.compose.ui.Modifier + +@Stable +/* +@LazyScopeMarker +@JvmDefaultWithCompatibility +*/ +actual object LazyItemScope { + // I am not sure whether these implementations work perfectly. + + actual fun Modifier.fillParentMaxSize( + @FloatRange(from = 0.0, to = 1.0) + fraction: Float + ): Modifier = + fillMaxSize(fraction) + + actual fun Modifier.fillParentMaxWidth( + @FloatRange(from = 0.0, to = 1.0) + fraction: Float + ): Modifier = + fillMaxWidth(fraction) + + actual fun Modifier.fillParentMaxHeight( + @FloatRange(from = 0.0, to = 1.0) + fraction: Float + ): Modifier = + fillMaxHeight(fraction) +} \ No newline at end of file diff --git a/compose-multiplatform-material/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material/lazy/ext/LazyDsl.androidxCommon.kt b/compose-multiplatform-material/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material/lazy/ext/LazyDsl.androidxCommon.kt index 6316c00d..cfa43729 100644 --- a/compose-multiplatform-material/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material/lazy/ext/LazyDsl.androidxCommon.kt +++ b/compose-multiplatform-material/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material/lazy/ext/LazyDsl.androidxCommon.kt @@ -6,7 +6,7 @@ import com.huanshankeji.compose.ui.Modifier import androidx.compose.foundation.lazy.LazyItemScope as PlatformLazyItemScope import androidx.compose.foundation.lazy.LazyListScope as PlatformLazyListScope -actual class LazyListScope(val platformValue: PlatformLazyListScope) { +actual class ListScope(val platformValue: PlatformLazyListScope) { actual fun item(key: Any?, contentType: Any?, content: @Composable LazyItemScope.() -> Unit) = platformValue.item(key, contentType) { LazyItemScope(this).content() } @@ -23,7 +23,7 @@ actual class LazyListScope(val platformValue: PlatformLazyListScope) { key: Any?, contentType: Any?, headerContent: @Composable HeaderScope.() -> Unit, - content: LazyListScope.() -> Unit + content: ListScope.() -> Unit ) { platformValue.stickyHeader(key, contentType) { HeaderScope(this).headerContent() } content() @@ -34,8 +34,8 @@ actual class LazyItemScope(val platformValue: PlatformLazyItemScope) actual typealias HeaderScope = LazyItemScope @Composable -actual fun LazyColumn(modifier: Modifier, content: LazyListScope.() -> Unit) = +actual fun List(modifier: Modifier, content: ListScope.() -> Unit) = // Note that it's actually in the `foundation` package. androidx.compose.foundation.lazy.LazyColumn(modifier.platformModifier) { - LazyListScope(this).content() + ListScope(this).content() } diff --git a/compose-multiplatform-material/src/commonMain/kotlin/com/huanshankeji/compose/material/lazy/ext/LazyDsl.kt b/compose-multiplatform-material/src/commonMain/kotlin/com/huanshankeji/compose/material/lazy/ext/LazyDsl.kt index 358ead26..f8d2ed11 100644 --- a/compose-multiplatform-material/src/commonMain/kotlin/com/huanshankeji/compose/material/lazy/ext/LazyDsl.kt +++ b/compose-multiplatform-material/src/commonMain/kotlin/com/huanshankeji/compose/material/lazy/ext/LazyDsl.kt @@ -4,7 +4,7 @@ import androidx.compose.runtime.Composable import com.huanshankeji.compose.ui.Modifier /** @see androidx.compose.foundation.lazy.LazyListScope */ -expect class LazyListScope { +expect class ListScope { fun item(key: Any? = null, contentType: Any? = null, content: @Composable LazyItemScope.() -> Unit) fun items( @@ -18,7 +18,7 @@ expect class LazyListScope { key: Any? = null, contentType: Any? = null, headerContent: @Composable HeaderScope.() -> Unit, - content: LazyListScope.() -> Unit + content: ListScope.() -> Unit ) } @@ -34,11 +34,11 @@ expect class HeaderScope * The current implementation is not actually lazy on web, but it seems not necessary to be. */ @Composable -expect fun LazyColumn(modifier: Modifier = Modifier, content: LazyListScope.() -> Unit) +expect fun List(modifier: Modifier = Modifier, content: ListScope.() -> Unit) /** - * An alias for [LazyColumn] that is more conventional for Web/HTML/JS. + * An alias for [List] that is more similar to `androidx.compose.foundation.layout.LazyColumn`. */ @Composable -fun ScrollableList(modifier: Modifier = Modifier, content: LazyListScope.() -> Unit) = - LazyColumn(modifier, content) +fun LazyColumnList(modifier: Modifier = Modifier, content: ListScope.() -> Unit) = + List(modifier, content) diff --git a/compose-multiplatform-material/src/jsMain/kotlin/com/huanshankeji/compose/material/lazy/ext/LazyDsl.js.kt b/compose-multiplatform-material/src/jsMain/kotlin/com/huanshankeji/compose/material/lazy/ext/LazyDsl.js.kt index dad37eb8..e45ab00a 100644 --- a/compose-multiplatform-material/src/jsMain/kotlin/com/huanshankeji/compose/material/lazy/ext/LazyDsl.js.kt +++ b/compose-multiplatform-material/src/jsMain/kotlin/com/huanshankeji/compose/material/lazy/ext/LazyDsl.js.kt @@ -1,6 +1,8 @@ package com.huanshankeji.compose.material.lazy.ext import androidx.compose.runtime.Composable +import com.huanshankeji.compose.foundation.lazy.columnOverflow +import com.huanshankeji.compose.runtime.DeferredComposableRunner import com.huanshankeji.compose.ui.Modifier import com.varabyte.kobweb.compose.ui.toAttrs import dev.petuska.kmdc.list.MDCList @@ -19,24 +21,17 @@ import org.w3c.dom.HTMLUListElement * This class contains mutable fields. * @see androidx.compose.foundation.lazy.LazyListScopeImpl */ -actual class LazyListScope( +actual class ListScope( val mdcListScope: MDCListScope ) { - private var composables: MutableList<@Composable () -> Unit>? = null - private fun addComposable(composable: @Composable () -> Unit) { - composables!!.add(composable) - } + private val deferredComposableRunner = DeferredComposableRunner() - /** Add the composable functions with the non-composable functions and then invoke them. */ - @Composable - fun ComposableRun(content: LazyListScope.() -> Unit) { - composables = mutableListOf() - content() - for (composable in composables!!) - composable() - composables = null - } + private fun addComposable(composable: @Composable () -> Unit) = + deferredComposableRunner.addComposable(composable) + @Composable + internal fun ComposableRun(content: ListScope.() -> Unit) = + deferredComposableRunner.ComposableRun { content() } actual fun item(key: Any?, contentType: Any?, content: @Composable LazyItemScope.() -> Unit) = addComposable { mdcListScope.ListItem { LazyItemScope(this).content() } @@ -57,14 +52,14 @@ actual class LazyListScope( key: Any?, contentType: Any?, headerContent: @Composable HeaderScope.() -> Unit, - content: LazyListScope.() -> Unit - ) = addComposable { + content: ListScope.() -> Unit + ) = deferredComposableRunner.addComposable { MDCListGroup { Subheader { HeaderScope(this).headerContent() } MDCList { - LazyListScope(this).ComposableRun(content) + ListScope(this).ComposableRun(content) } } } @@ -74,12 +69,11 @@ actual class LazyItemScope(val mdcListItemScope: MDCListItemScope actual class HeaderScope(val headingElementScope: ElementScope) @Composable -actual fun LazyColumn(modifier: Modifier, content: LazyListScope.() -> Unit) = +actual fun List(modifier: Modifier, content: ListScope.() -> Unit) = MDCList(attrs = modifier.platformModifier.toAttrs { style { - //overflowY("scroll") - overflowY("auto") + columnOverflow() } }) { - LazyListScope(this).ComposableRun(content) + ListScope(this).ComposableRun(content) } diff --git a/compose-multiplatform-material3/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material3/ext/FloatingActionButton.androidxCommon.kt b/compose-multiplatform-material3/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material3/ext/FloatingActionButton.androidxCommon.kt index 56d85627..8f6c31ed 100644 --- a/compose-multiplatform-material3/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material3/ext/FloatingActionButton.androidxCommon.kt +++ b/compose-multiplatform-material3/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material3/ext/FloatingActionButton.androidxCommon.kt @@ -2,12 +2,9 @@ package com.huanshankeji.compose.material3.ext import androidx.compose.material3.Text import androidx.compose.runtime.Composable +import com.huanshankeji.compose.toContentWithoutModifier import com.huanshankeji.compose.ui.Modifier -private fun (@Composable (Modifier) -> Unit).toContentWithoutModifier(): @Composable () -> Unit = - { this(Modifier) } - - @Composable actual fun FloatingActionButton( onClick: () -> Unit, diff --git a/compose-multiplatform-material3/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material3/lazy/ext/List.androidxCommon.kt b/compose-multiplatform-material3/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material3/lazy/ext/List.androidxCommon.kt new file mode 100644 index 00000000..3d9ff286 --- /dev/null +++ b/compose-multiplatform-material3/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material3/lazy/ext/List.androidxCommon.kt @@ -0,0 +1,77 @@ +package com.huanshankeji.compose.material3.lazy.ext + +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.lazy.LazyColumn +import androidx.compose.foundation.lazy.LazyListScope +import androidx.compose.material3.ListItem +import androidx.compose.runtime.Composable +import com.huanshankeji.compose.toNullableContentWithoutModifier +import com.huanshankeji.compose.ui.Modifier + +actual class ListScope(val lazyListScope: LazyListScope) { + @Composable + private fun ListItem(content: ListItemComponents) = + with(content) { + ListItem( + headline.toNullableContentWithoutModifier() ?: {}, + contentModifier.platformModifier, + overline.toNullableContentWithoutModifier(), + supportingText.toNullableContentWithoutModifier(), + start.toNullableContentWithoutModifier(), + trailingSupportingText?.let { trailingSupportingText -> + end?.let { end -> + { + Row { + trailingSupportingText(Modifier) + end(Modifier) + } + } + } ?: { trailingSupportingText(Modifier) } + } ?: end?.let { end -> + { end(Modifier) } + } + ) + } + + + actual fun item( + key: Any?, + contentType: Any?, + content: @Composable () -> Unit + ) = + lazyListScope.item(key, contentType) { content() } + + actual fun conventionalItem( + key: Any?, + contentType: Any?, + content: ListItemComponents + ) = + item(key, contentType) { ListItem(content) } + + actual fun items( + count: Int, + key: ((index: Int) -> Any)?, + contentType: (index: Int) -> Any?, + itemContent: @Composable (index: Int) -> Unit + ) = + lazyListScope.items(count, key, contentType) { index -> itemContent(index) } + + actual fun conventionalItems( + count: Int, + key: ((index: Int) -> Any)?, + contentType: (index: Int) -> Any?, + itemContent: (index: Int) -> ListItemComponents + ) = + items(count, key, contentType) { index -> + ListItem(itemContent(index)) + } +} + +@Composable +actual fun List( + modifier: Modifier, + content: ListScope.() -> Unit +) = + LazyColumn(modifier.platformModifier) { + ListScope(this).content() + } diff --git a/compose-multiplatform-material3/src/commonMain/kotlin/com/huanshankeji/compose/material3/ext/Icon.kt b/compose-multiplatform-material3/src/commonMain/kotlin/com/huanshankeji/compose/material3/ext/Icon.kt index b1dfb26a..496ff952 100644 --- a/compose-multiplatform-material3/src/commonMain/kotlin/com/huanshankeji/compose/material3/ext/Icon.kt +++ b/compose-multiplatform-material3/src/commonMain/kotlin/com/huanshankeji/compose/material3/ext/Icon.kt @@ -9,4 +9,4 @@ fun Icon.toContentWithModifier(): @Composable (Modifier) -> Unit = { modifier -> Icon(this, null, modifier) } fun Icon?.toNullableContentWithModifier(): @Composable ((Modifier) -> Unit)? = - this?.run { toContentWithModifier() } + this?.toContentWithModifier() diff --git a/compose-multiplatform-material3/src/commonMain/kotlin/com/huanshankeji/compose/material3/ext/Text.kt b/compose-multiplatform-material3/src/commonMain/kotlin/com/huanshankeji/compose/material3/ext/Text.kt index 0e10df5f..4d0c81d3 100644 --- a/compose-multiplatform-material3/src/commonMain/kotlin/com/huanshankeji/compose/material3/ext/Text.kt +++ b/compose-multiplatform-material3/src/commonMain/kotlin/com/huanshankeji/compose/material3/ext/Text.kt @@ -17,3 +17,10 @@ inline fun MaterialText(text: String, modifier: Modifier = Modifier) = */ @Composable expect fun InlineText(text: String) + + +fun String.toTextWithModifier(): @Composable (Modifier) -> Unit = + { modifier -> Text(this, modifier) } + +fun String?.toNullableTextWithModifier(): @Composable ((Modifier) -> Unit)? = + this?.toTextWithModifier() diff --git a/compose-multiplatform-material3/src/commonMain/kotlin/com/huanshankeji/compose/material3/lazy/ext/List.kt b/compose-multiplatform-material3/src/commonMain/kotlin/com/huanshankeji/compose/material3/lazy/ext/List.kt new file mode 100644 index 00000000..94fff404 --- /dev/null +++ b/compose-multiplatform-material3/src/commonMain/kotlin/com/huanshankeji/compose/material3/lazy/ext/List.kt @@ -0,0 +1,67 @@ +package com.huanshankeji.compose.material3.lazy.ext + +import androidx.compose.runtime.Composable +import com.huanshankeji.compose.material.icons.Icon +import com.huanshankeji.compose.material3.ext.toNullableContentWithModifier +import com.huanshankeji.compose.material3.ext.toNullableTextWithModifier +import com.huanshankeji.compose.ui.Modifier + +expect class ListScope { + fun item(key: Any? = null, contentType: Any? = null, content: @Composable () -> Unit) + + // the word "conventional" added to be consistent with `conventionalItems` + fun conventionalItem(key: Any? = null, contentType: Any? = null, content: ListItemComponents) + + fun items( + count: Int, + key: ((index: Int) -> Any)? = null, + contentType: (index: Int) -> Any? = { null }, + itemContent: @Composable (index: Int) -> Unit + ) + + // the word "conventional" added to avoid clashing with `items` + fun conventionalItems( + count: Int, + key: ((index: Int) -> Any)? = null, + contentType: (index: Int) -> Any? = { null }, + itemContent: (index: Int) -> ListItemComponents + ) +} + +class ListItemComponents( + val contentModifier: Modifier = Modifier, + val headline: @Composable ((Modifier) -> Unit)? = null, + val start: @Composable ((Modifier) -> Unit)? = null, + val end: @Composable ((Modifier) -> Unit)? = null, + val supportingText: @Composable ((Modifier) -> Unit)? = null, + val trailingSupportingText: @Composable ((Modifier) -> Unit)? = null, + val overline: @Composable ((Modifier) -> Unit)? = null +) { + constructor( + contentModifier: Modifier = Modifier, + headline: String? = null, + start: Icon? = null, + end: Icon? = null, + supportingText: String? = null, + trailingSupportingText: String? = null, + overline: String? = null + ) : this( + contentModifier, + headline.toNullableTextWithModifier(), + start.toNullableContentWithModifier(), + end.toNullableContentWithModifier(), + supportingText.toNullableTextWithModifier(), + trailingSupportingText.toNullableTextWithModifier(), + overline.toNullableTextWithModifier() + ) +} + +@Composable +expect fun List(modifier: Modifier = Modifier, content: ListScope.() -> Unit) + +/** + * An alias for [List] that is more similar to `androidx.compose.foundation.layout.LazyColumn`. + */ +@Composable +fun LazyColumnList(modifier: Modifier = Modifier, content: ListScope.() -> Unit) = + List(modifier, content) diff --git a/compose-multiplatform-material3/src/jsMain/kotlin/com/huanshankeji/compose/material3/lazy/ext/List.js.kt b/compose-multiplatform-material3/src/jsMain/kotlin/com/huanshankeji/compose/material3/lazy/ext/List.js.kt new file mode 100644 index 00000000..46c0240c --- /dev/null +++ b/compose-multiplatform-material3/src/jsMain/kotlin/com/huanshankeji/compose/material3/lazy/ext/List.js.kt @@ -0,0 +1,97 @@ +package com.huanshankeji.compose.material3.lazy.ext + +import androidx.compose.runtime.Composable +import com.huanshankeji.compose.foundation.lazy.columnOverflow +import com.huanshankeji.compose.html.material3.MdList +import com.huanshankeji.compose.html.material3.MdListItemScope +import com.huanshankeji.compose.html.material3.MdListScope +import com.huanshankeji.compose.runtime.DeferredComposableRunner +import com.huanshankeji.compose.ui.Modifier +import com.huanshankeji.compose.ui.toCommonModifier +import com.varabyte.kobweb.compose.ui.attrsModifier +import com.varabyte.kobweb.compose.ui.toAttrs +import com.varabyte.kobweb.compose.ui.Modifier as PlatformModifier + +@Composable +private fun MdListItemScope.contentFromComponents(listItemComponents: ListItemComponents) = with(listItemComponents) { + headline?.invoke(PlatformModifier.attrsModifier { slot(MdListItemScope.Slot.Headline) }.toCommonModifier()) + start?.invoke(PlatformModifier.attrsModifier { slot(MdListItemScope.Slot.Start) }.toCommonModifier()) + end?.invoke(PlatformModifier.attrsModifier { slot(MdListItemScope.Slot.End) }.toCommonModifier()) + supportingText?.invoke( + PlatformModifier.attrsModifier { slot(MdListItemScope.Slot.SupportingText) }.toCommonModifier() + ) + trailingSupportingText?.invoke( + PlatformModifier.attrsModifier { slot(MdListItemScope.Slot.TrailingSupportingText) }.toCommonModifier() + ) + overline?.invoke(PlatformModifier.attrsModifier { slot(MdListItemScope.Slot.Overline) }.toCommonModifier()) +} + +actual class ListScope(val mdListScope: MdListScope) { + private val deferredComposableRunner = DeferredComposableRunner() + + private fun addComposable(composable: @Composable () -> Unit) = + deferredComposableRunner.addComposable(composable) + + @Composable + internal fun ComposableRun(content: ListScope.() -> Unit) = + deferredComposableRunner.ComposableRun { content() } + + + @Composable + private fun ListItem(content: ListItemComponents) = + mdListScope.MdListItem(attrs = content.contentModifier.platformModifier.toAttrs()) { + contentFromComponents(content) + } + + + actual fun item( + key: Any?, + contentType: Any?, + content: @Composable () -> Unit + ) = addComposable { + mdListScope.MdListItem { content() } + } + + actual fun conventionalItem( + key: Any?, + contentType: Any?, + content: ListItemComponents + ) = addComposable { + ListItem(content) + } + + actual fun items( + count: Int, + key: ((index: Int) -> Any)?, + contentType: (index: Int) -> Any?, + itemContent: @Composable (index: Int) -> Unit + ) = addComposable { + repeat(count) { index -> + mdListScope.MdListItem { itemContent(index) } + } + } + + actual fun conventionalItems( + count: Int, + key: ((index: Int) -> Any)?, + contentType: (index: Int) -> Any?, + itemContent: (index: Int) -> ListItemComponents + ) = addComposable { + repeat(count) { index -> + ListItem(itemContent(index)) + } + } +} + +@Composable +actual fun List( + modifier: Modifier, + content: ListScope.() -> Unit +) = + MdList(modifier.platformModifier.toAttrs { + style { + columnOverflow() + } + }) { + ListScope(this).ComposableRun(content) + } diff --git a/demo/src/commonMain/kotlin/com/huanshankeji/compose/material/demo/App.kt b/demo/src/commonMain/kotlin/com/huanshankeji/compose/material/demo/App.kt index 83083362..d1dfa540 100644 --- a/demo/src/commonMain/kotlin/com/huanshankeji/compose/material/demo/App.kt +++ b/demo/src/commonMain/kotlin/com/huanshankeji/compose/material/demo/App.kt @@ -1,28 +1,28 @@ package com.huanshankeji.compose.material.demo import androidx.compose.runtime.Composable +import androidx.compose.ui.unit.dp import com.huanshankeji.compose.foundation.layout.Box -import com.huanshankeji.compose.foundation.layout.Column import com.huanshankeji.compose.foundation.layout.Row -import com.huanshankeji.compose.foundation.text.BasicText import com.huanshankeji.compose.ui.Modifier internal enum class RadioButtonState { A, B, C } +val listSize = 160.dp + @Composable fun App() { - Column { - BasicText("basic text 1") - BasicText("basic text 2") - Row { - Box(Modifier.weight(1f)) { - Material2() - } - Box(Modifier.weight(1f)) { - Material3() - } + Row { + Box(Modifier.weight(1f)) { + Common() + } + Box(Modifier.weight(1f)) { + Material2() + } + Box(Modifier.weight(1f)) { + Material3() } } } diff --git a/demo/src/commonMain/kotlin/com/huanshankeji/compose/material/demo/Common.kt b/demo/src/commonMain/kotlin/com/huanshankeji/compose/material/demo/Common.kt new file mode 100644 index 00000000..8d06f420 --- /dev/null +++ b/demo/src/commonMain/kotlin/com/huanshankeji/compose/material/demo/Common.kt @@ -0,0 +1,68 @@ +package com.huanshankeji.compose.material.demo + +import androidx.compose.runtime.* +import androidx.compose.ui.unit.dp +import com.huanshankeji.compose.foundation.background +import com.huanshankeji.compose.foundation.border +import com.huanshankeji.compose.foundation.ext.outerBorder +import com.huanshankeji.compose.foundation.ext.roundedCornerBackgroundAndOuterBorder +import com.huanshankeji.compose.foundation.ext.roundedCornerOuterBorder +import com.huanshankeji.compose.foundation.layout.Box +import com.huanshankeji.compose.foundation.layout.Column +import com.huanshankeji.compose.foundation.layout.Row +import com.huanshankeji.compose.foundation.lazy.LazyColumn +import com.huanshankeji.compose.foundation.lazy.LazyListScope +import com.huanshankeji.compose.foundation.lazy.LazyRow +import com.huanshankeji.compose.foundation.onClick +import com.huanshankeji.compose.foundation.text.BasicText +import com.huanshankeji.compose.layout.height +import com.huanshankeji.compose.layout.padding +import com.huanshankeji.compose.layout.size +import com.huanshankeji.compose.layout.width +import com.huanshankeji.compose.material.Divider +import com.huanshankeji.compose.ui.Modifier +import com.huanshankeji.compose.ui.graphics.Color + +@Composable +fun Common() { + Column { + BasicText("basic text 1") + BasicText("basic text 2") + + @Composable + fun ColorBox(color: Color) = + Box(Modifier.padding(8.dp).background(color).size(40.dp)) + + val halfGreen = Color(0, 0x80, 0x00) + + Row(Modifier.roundedCornerBackgroundAndOuterBorder(4.dp, Color.Blue, 16.dp, halfGreen)) { + ColorBox(Color.Red) + ColorBox(Color(0xFF, 0, 0)) + ColorBox(Color(0xFF, 0, 0, 0x80)) + ColorBox(Color(1f, 0f, 0f, 0.5f)) + } + + Divider() + + Row { + @Composable + fun NestedColorBox(modifier: Modifier) = + Box(modifier.background(halfGreen)) { ColorBox(Color.Red) } + + NestedColorBox(Modifier.border(4.dp, Color.Blue)) + NestedColorBox(Modifier.outerBorder(4.dp, Color.Blue)) + NestedColorBox(Modifier.roundedCornerOuterBorder(4.dp, Color.Blue, 16.dp)) + NestedColorBox(Modifier.roundedCornerOuterBorder(1.dp, Color.Blue, 16.dp)) + val transparentBlue = Color(0, 0, 0x80, 0x80) + Box(Modifier.roundedCornerBackgroundAndOuterBorder(2.dp, transparentBlue, 16.dp, halfGreen)) { + ColorBox(Color.Red) + } + } + + var count by remember { mutableStateOf(0) } + BasicText("Click to add items to `LazyColumn` and `LazyRow`", Modifier.onClick { count++ }) + val content: LazyListScope.() -> Unit = { items(count) { index -> BasicText("Item $index") } } + LazyColumn(Modifier.height(listSize), content = content) + LazyRow(Modifier.width(listSize), content = content) + } +} \ No newline at end of file diff --git a/demo/src/commonMain/kotlin/com/huanshankeji/compose/material/demo/Material2.kt b/demo/src/commonMain/kotlin/com/huanshankeji/compose/material/demo/Material2.kt index 52581b11..275fe1ff 100644 --- a/demo/src/commonMain/kotlin/com/huanshankeji/compose/material/demo/Material2.kt +++ b/demo/src/commonMain/kotlin/com/huanshankeji/compose/material/demo/Material2.kt @@ -3,10 +3,6 @@ package com.huanshankeji.compose.material.demo import androidx.compose.runtime.* import androidx.compose.ui.unit.dp import com.huanshankeji.compose.foundation.background -import com.huanshankeji.compose.foundation.border -import com.huanshankeji.compose.foundation.ext.outerBorder -import com.huanshankeji.compose.foundation.ext.roundedCornerBackgroundAndOuterBorder -import com.huanshankeji.compose.foundation.ext.roundedCornerOuterBorder import com.huanshankeji.compose.foundation.layout.Box import com.huanshankeji.compose.foundation.layout.Column import com.huanshankeji.compose.foundation.layout.Row @@ -18,7 +14,6 @@ import com.huanshankeji.compose.foundation.text.input.KeyboardCapitalization import com.huanshankeji.compose.foundation.text.input.KeyboardType import com.huanshankeji.compose.layout.height import com.huanshankeji.compose.layout.padding -import com.huanshankeji.compose.layout.size import com.huanshankeji.compose.layout.width import com.huanshankeji.compose.material.* import com.huanshankeji.compose.material.ext.* @@ -26,7 +21,7 @@ import com.huanshankeji.compose.material.icons.Icons import com.huanshankeji.compose.material.icons.filled.Add import com.huanshankeji.compose.material.icons.filled.Menu import com.huanshankeji.compose.material.icons.filled.Search -import com.huanshankeji.compose.material.lazy.ext.LazyColumn +import com.huanshankeji.compose.material.lazy.ext.List import com.huanshankeji.compose.ui.Modifier import com.huanshankeji.compose.ui.graphics.Color import com.huanshankeji.compose.material.ext.Button as ExtButton @@ -62,7 +57,7 @@ fun Material2() { } Box(Modifier.padding(16.dp)) { - LazyColumn(Modifier.height(100.dp)) { + List(Modifier.height(listSize)) { item { Text("Ungrouped item") } @@ -82,36 +77,6 @@ fun Material2() { } } - @Composable - fun ColorBox(color: Color) = - Box(Modifier.padding(8.dp).background(color).size(40.dp)) - - val halfGreen = Color(0, 0x80, 0x00) - - Row(Modifier.roundedCornerBackgroundAndOuterBorder(4.dp, Color.Blue, 16.dp, halfGreen)) { - ColorBox(Color.Red) - ColorBox(Color(0xFF, 0, 0)) - ColorBox(Color(0xFF, 0, 0, 0x80)) - ColorBox(Color(1f, 0f, 0f, 0.5f)) - } - - Divider() - - Row { - @Composable - fun NestedColorBox(modifier: Modifier) = - Box(modifier.background(halfGreen)) { ColorBox(Color.Red) } - - NestedColorBox(Modifier.border(4.dp, Color.Blue)) - NestedColorBox(Modifier.outerBorder(4.dp, Color.Blue)) - NestedColorBox(Modifier.roundedCornerOuterBorder(4.dp, Color.Blue, 16.dp)) - NestedColorBox(Modifier.roundedCornerOuterBorder(1.dp, Color.Blue, 16.dp)) - val transparentBlue = Color(0, 0, 0x80, 0x80) - Box(Modifier.roundedCornerBackgroundAndOuterBorder(2.dp, transparentBlue, 16.dp, halfGreen)) { - ColorBox(Color.Red) - } - } - var text by remember { mutableStateOf("") } TextFieldWithMaterialIcons( text, { text = it }, diff --git a/demo/src/commonMain/kotlin/com/huanshankeji/compose/material/demo/Material3.kt b/demo/src/commonMain/kotlin/com/huanshankeji/compose/material/demo/Material3.kt index a7cc1075..3b4d0b97 100644 --- a/demo/src/commonMain/kotlin/com/huanshankeji/compose/material/demo/Material3.kt +++ b/demo/src/commonMain/kotlin/com/huanshankeji/compose/material/demo/Material3.kt @@ -10,12 +10,16 @@ import com.huanshankeji.compose.foundation.text.KeyboardOptions import com.huanshankeji.compose.foundation.text.input.ImeAction import com.huanshankeji.compose.foundation.text.input.KeyboardCapitalization import com.huanshankeji.compose.foundation.text.input.KeyboardType +import com.huanshankeji.compose.layout.height import com.huanshankeji.compose.material.icons.Icons import com.huanshankeji.compose.material.icons.filled.Add import com.huanshankeji.compose.material.icons.filled.Menu import com.huanshankeji.compose.material.icons.filled.Remove import com.huanshankeji.compose.material3.* import com.huanshankeji.compose.material3.ext.* +import com.huanshankeji.compose.material3.lazy.ext.List +import com.huanshankeji.compose.material3.lazy.ext.ListItemComponents +import com.huanshankeji.compose.ui.Modifier import com.huanshankeji.compose.material3.Button as RowScopeButton @Composable @@ -133,5 +137,20 @@ fun Material3() { println("keyboard actions with: $text") } ) + + Text("Click a button to show the list:") + List(Modifier.height(listSize)) { + conventionalItems(count) { index -> + ListItemComponents( + Modifier, + "Headline $index", + Icons.Default.Add, + Icons.Default.Menu, + "Supporting text $index", + "Trailing supporting text $index", + "Overline $index" + ) + } + } } } From b248a51b9a7a9712b381e471f78ead974df19714 Mon Sep 17 00:00:00 2001 From: Shreck Ye Date: Wed, 8 May 2024 00:19:50 +0800 Subject: [PATCH 62/75] Revamp both the Material 2 `List` and the Material 3 `List` See the previous commit for more details. --- .../lazy/ext/LazyDsl.androidxCommon.kt | 23 +++++++--- .../com/huanshankeji/compose/material/Text.kt | 2 + .../compose/material/lazy/ext/LazyDsl.kt | 42 ++++++++++++++---- .../compose/material/lazy/ext/LazyDsl.js.kt | 22 +++++++--- .../material3/lazy/ext/List.androidxCommon.kt | 14 +++--- .../huanshankeji/compose/material3/Text.kt | 2 + .../compose/material3/lazy/ext/List.kt | 13 +++--- .../compose/material3/lazy/ext/List.js.kt | 12 ++--- .../compose/material/demo/Common.kt | 5 ++- .../compose/material/demo/Material2.kt | 44 +++++++++++++------ .../compose/material/demo/Material3.kt | 5 ++- 11 files changed, 131 insertions(+), 53 deletions(-) diff --git a/compose-multiplatform-material/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material/lazy/ext/LazyDsl.androidxCommon.kt b/compose-multiplatform-material/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material/lazy/ext/LazyDsl.androidxCommon.kt index cfa43729..f281dd45 100644 --- a/compose-multiplatform-material/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material/lazy/ext/LazyDsl.androidxCommon.kt +++ b/compose-multiplatform-material/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material/lazy/ext/LazyDsl.androidxCommon.kt @@ -1,37 +1,46 @@ package com.huanshankeji.compose.material.lazy.ext import androidx.compose.foundation.ExperimentalFoundationApi +import androidx.compose.material.ExperimentalMaterialApi +import androidx.compose.material.ListItem import androidx.compose.runtime.Composable import com.huanshankeji.compose.ui.Modifier import androidx.compose.foundation.lazy.LazyItemScope as PlatformLazyItemScope import androidx.compose.foundation.lazy.LazyListScope as PlatformLazyListScope actual class ListScope(val platformValue: PlatformLazyListScope) { - actual fun item(key: Any?, contentType: Any?, content: @Composable LazyItemScope.() -> Unit) = - platformValue.item(key, contentType) { LazyItemScope(this).content() } + actual fun item(key: Any?, contentType: Any?, content: @Composable ItemScope.() -> Unit) = + platformValue.item(key, contentType) { ItemScope(this).content() } actual fun items( count: Int, key: ((index: Int) -> Any)?, contentType: (index: Int) -> Any?, - itemContent: @Composable LazyItemScope.(index: Int) -> Unit + itemContent: @Composable ItemScope.(index: Int) -> Unit ) = - platformValue.items(count, key, contentType) { LazyItemScope(this).itemContent(it) } + platformValue.items(count, key, contentType) { ItemScope(this).itemContent(it) } - @OptIn(ExperimentalFoundationApi::class) actual fun group( key: Any?, contentType: Any?, headerContent: @Composable HeaderScope.() -> Unit, content: ListScope.() -> Unit ) { + @OptIn(ExperimentalFoundationApi::class) platformValue.stickyHeader(key, contentType) { HeaderScope(this).headerContent() } content() } + + @Composable + actual fun ItemScope.ListItemContent(listItemComponents: ListItemComponents) = + with(listItemComponents) { + @OptIn(ExperimentalMaterialApi::class) + ListItem(secondaryText = secondaryText, text = text) + } } -actual class LazyItemScope(val platformValue: PlatformLazyItemScope) -actual typealias HeaderScope = LazyItemScope +actual class ItemScope(val platformValue: PlatformLazyItemScope) +actual typealias HeaderScope = ItemScope @Composable actual fun List(modifier: Modifier, content: ListScope.() -> Unit) = diff --git a/compose-multiplatform-material/src/commonMain/kotlin/com/huanshankeji/compose/material/Text.kt b/compose-multiplatform-material/src/commonMain/kotlin/com/huanshankeji/compose/material/Text.kt index 1de5ceef..23534f87 100644 --- a/compose-multiplatform-material/src/commonMain/kotlin/com/huanshankeji/compose/material/Text.kt +++ b/compose-multiplatform-material/src/commonMain/kotlin/com/huanshankeji/compose/material/Text.kt @@ -1,6 +1,7 @@ package com.huanshankeji.compose.material import androidx.compose.runtime.Composable +import com.huanshankeji.compose.material.ext.InlineText import com.huanshankeji.compose.ui.Modifier /** @@ -8,6 +9,7 @@ import com.huanshankeji.compose.ui.Modifier * can be easily confused with other Composable functions named `Text` * such as `androidx.compose.material.Text` and `org.jetbrains.compose.web.dom.Text` * if not careful. + * [InlineText] is recommended over this one when there is no custom [modifier]. * @see com.huanshankeji.compose.material.ext.MaterialText */ @Composable diff --git a/compose-multiplatform-material/src/commonMain/kotlin/com/huanshankeji/compose/material/lazy/ext/LazyDsl.kt b/compose-multiplatform-material/src/commonMain/kotlin/com/huanshankeji/compose/material/lazy/ext/LazyDsl.kt index f8d2ed11..fdca7ca1 100644 --- a/compose-multiplatform-material/src/commonMain/kotlin/com/huanshankeji/compose/material/lazy/ext/LazyDsl.kt +++ b/compose-multiplatform-material/src/commonMain/kotlin/com/huanshankeji/compose/material/lazy/ext/LazyDsl.kt @@ -1,17 +1,17 @@ package com.huanshankeji.compose.material.lazy.ext import androidx.compose.runtime.Composable +import com.huanshankeji.compose.material.ext.InlineText import com.huanshankeji.compose.ui.Modifier -/** @see androidx.compose.foundation.lazy.LazyListScope */ expect class ListScope { - fun item(key: Any? = null, contentType: Any? = null, content: @Composable LazyItemScope.() -> Unit) + fun item(key: Any? = null, contentType: Any? = null, content: @Composable ItemScope.() -> Unit) fun items( count: Int, key: ((index: Int) -> Any)? = null, contentType: (index: Int) -> Any? = { null }, - itemContent: @Composable LazyItemScope.(index: Int) -> Unit + itemContent: @Composable ItemScope.(index: Int) -> Unit ) fun group( @@ -20,16 +20,42 @@ expect class ListScope { headerContent: @Composable HeaderScope.() -> Unit, content: ListScope.() -> Unit ) + + @Composable + fun ItemScope.ListItemContent(listItemComponents: ListItemComponents) } -expect class LazyItemScope /*{ - fun Modifier.fillParentMaxSize(@FloatRange(from = 0.0, to = 1.0) fraction: Float = 1f): Modifier - fun Modifier.fillParentMaxWidth(@FloatRange(from = 0.0, to = 1.0) fraction: Float = 1f): Modifier - fun Modifier.fillParentMaxHeight(@FloatRange(from = 0.0, to = 1.0) fraction: Float = 1f): Modifier -}*/ +expect class ItemScope expect class HeaderScope +class ListItemComponents( + val text: @Composable () -> Unit, + val secondaryText: @Composable (() -> Unit)? = null +) { + constructor(text: String, secondaryText: String? = null) : this( + { InlineText(text) }, + secondaryText?.let { { InlineText(it) } } + ) +} + +// see https://youtrack.jetbrains.com/issue/KT-20427 + +fun ListScope.conventionalItem(key: Any? = null, contentType: Any? = null, content: ListItemComponents) = + item(key, contentType) { + ListItemContent(content) + } + +fun ListScope.conventionalItems( + count: Int, + key: ((index: Int) -> Any)? = null, + contentType: (index: Int) -> Any? = { null }, + itemContent: (index: Int) -> ListItemComponents +) = + items(count, key, contentType) { index -> + ListItemContent(itemContent(index)) + } + /** * The current implementation is not actually lazy on web, but it seems not necessary to be. */ diff --git a/compose-multiplatform-material/src/jsMain/kotlin/com/huanshankeji/compose/material/lazy/ext/LazyDsl.js.kt b/compose-multiplatform-material/src/jsMain/kotlin/com/huanshankeji/compose/material/lazy/ext/LazyDsl.js.kt index e45ab00a..708cdd22 100644 --- a/compose-multiplatform-material/src/jsMain/kotlin/com/huanshankeji/compose/material/lazy/ext/LazyDsl.js.kt +++ b/compose-multiplatform-material/src/jsMain/kotlin/com/huanshankeji/compose/material/lazy/ext/LazyDsl.js.kt @@ -9,8 +9,7 @@ import dev.petuska.kmdc.list.MDCList import dev.petuska.kmdc.list.MDCListGroup import dev.petuska.kmdc.list.MDCListScope import dev.petuska.kmdc.list.Subheader -import dev.petuska.kmdc.list.item.ListItem -import dev.petuska.kmdc.list.item.MDCListItemScope +import dev.petuska.kmdc.list.item.* import org.jetbrains.compose.web.css.* import org.jetbrains.compose.web.dom.ElementScope import org.w3c.dom.HTMLHeadingElement @@ -33,18 +32,18 @@ actual class ListScope( internal fun ComposableRun(content: ListScope.() -> Unit) = deferredComposableRunner.ComposableRun { content() } - actual fun item(key: Any?, contentType: Any?, content: @Composable LazyItemScope.() -> Unit) = addComposable { - mdcListScope.ListItem { LazyItemScope(this).content() } + actual fun item(key: Any?, contentType: Any?, content: @Composable ItemScope.() -> Unit) = addComposable { + mdcListScope.ListItem { ItemScope(this).content() } } actual fun items( count: Int, key: ((index: Int) -> Any)?, contentType: (index: Int) -> Any?, - itemContent: @Composable LazyItemScope.(index: Int) -> Unit + itemContent: @Composable ItemScope.(index: Int) -> Unit ) = addComposable { repeat(count) { i -> - mdcListScope.ListItem { LazyItemScope(this).itemContent(i) } + mdcListScope.ListItem { ItemScope(this).itemContent(i) } } } @@ -63,9 +62,18 @@ actual class ListScope( } } } + + @Composable + actual fun ItemScope.ListItemContent(listItemComponents: ListItemComponents) = + with(listItemComponents) { + mdcListItemScope.Label { + Primary { text() } + secondaryText?.let { Secondary { it() } } + } + } } -actual class LazyItemScope(val mdcListItemScope: MDCListItemScope) +actual class ItemScope(val mdcListItemScope: MDCListItemScope) actual class HeaderScope(val headingElementScope: ElementScope) @Composable diff --git a/compose-multiplatform-material3/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material3/lazy/ext/List.androidxCommon.kt b/compose-multiplatform-material3/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material3/lazy/ext/List.androidxCommon.kt index 3d9ff286..42c4cb28 100644 --- a/compose-multiplatform-material3/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material3/lazy/ext/List.androidxCommon.kt +++ b/compose-multiplatform-material3/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material3/lazy/ext/List.androidxCommon.kt @@ -2,9 +2,11 @@ package com.huanshankeji.compose.material3.lazy.ext import androidx.compose.foundation.layout.Row import androidx.compose.foundation.lazy.LazyColumn +import androidx.compose.foundation.lazy.LazyItemScope import androidx.compose.foundation.lazy.LazyListScope import androidx.compose.material3.ListItem import androidx.compose.runtime.Composable +import com.huanshankeji.compose.toContentWithoutModifier import com.huanshankeji.compose.toNullableContentWithoutModifier import com.huanshankeji.compose.ui.Modifier @@ -13,7 +15,7 @@ actual class ListScope(val lazyListScope: LazyListScope) { private fun ListItem(content: ListItemComponents) = with(content) { ListItem( - headline.toNullableContentWithoutModifier() ?: {}, + headline.toContentWithoutModifier(), contentModifier.platformModifier, overline.toNullableContentWithoutModifier(), supportingText.toNullableContentWithoutModifier(), @@ -37,9 +39,9 @@ actual class ListScope(val lazyListScope: LazyListScope) { actual fun item( key: Any?, contentType: Any?, - content: @Composable () -> Unit + content: @Composable ItemScope.() -> Unit ) = - lazyListScope.item(key, contentType) { content() } + lazyListScope.item(key, contentType) { ItemScope(this).content() } actual fun conventionalItem( key: Any?, @@ -52,9 +54,9 @@ actual class ListScope(val lazyListScope: LazyListScope) { count: Int, key: ((index: Int) -> Any)?, contentType: (index: Int) -> Any?, - itemContent: @Composable (index: Int) -> Unit + itemContent: @Composable ItemScope.(index: Int) -> Unit ) = - lazyListScope.items(count, key, contentType) { index -> itemContent(index) } + lazyListScope.items(count, key, contentType) { index -> ItemScope(this).itemContent(index) } actual fun conventionalItems( count: Int, @@ -67,6 +69,8 @@ actual class ListScope(val lazyListScope: LazyListScope) { } } +actual class ItemScope(val lazyItemScope: LazyItemScope) + @Composable actual fun List( modifier: Modifier, diff --git a/compose-multiplatform-material3/src/commonMain/kotlin/com/huanshankeji/compose/material3/Text.kt b/compose-multiplatform-material3/src/commonMain/kotlin/com/huanshankeji/compose/material3/Text.kt index 13dfb570..3ae5a7de 100644 --- a/compose-multiplatform-material3/src/commonMain/kotlin/com/huanshankeji/compose/material3/Text.kt +++ b/compose-multiplatform-material3/src/commonMain/kotlin/com/huanshankeji/compose/material3/Text.kt @@ -1,6 +1,7 @@ package com.huanshankeji.compose.material3 import androidx.compose.runtime.Composable +import com.huanshankeji.compose.material3.ext.InlineText import com.huanshankeji.compose.ui.Modifier /** @@ -8,6 +9,7 @@ import com.huanshankeji.compose.ui.Modifier * can be easily confused with other Composable functions named `Text` * such as `androidx.compose.material.Text` and `org.jetbrains.compose.web.dom.Text` * if not careful. + * [InlineText] is recommended over this one when there is no custom [modifier]. * @see com.huanshankeji.compose.material3.ext.MaterialText */ @Composable diff --git a/compose-multiplatform-material3/src/commonMain/kotlin/com/huanshankeji/compose/material3/lazy/ext/List.kt b/compose-multiplatform-material3/src/commonMain/kotlin/com/huanshankeji/compose/material3/lazy/ext/List.kt index 94fff404..ef397ade 100644 --- a/compose-multiplatform-material3/src/commonMain/kotlin/com/huanshankeji/compose/material3/lazy/ext/List.kt +++ b/compose-multiplatform-material3/src/commonMain/kotlin/com/huanshankeji/compose/material3/lazy/ext/List.kt @@ -4,10 +4,11 @@ import androidx.compose.runtime.Composable import com.huanshankeji.compose.material.icons.Icon import com.huanshankeji.compose.material3.ext.toNullableContentWithModifier import com.huanshankeji.compose.material3.ext.toNullableTextWithModifier +import com.huanshankeji.compose.material3.ext.toTextWithModifier import com.huanshankeji.compose.ui.Modifier expect class ListScope { - fun item(key: Any? = null, contentType: Any? = null, content: @Composable () -> Unit) + fun item(key: Any? = null, contentType: Any? = null, content: @Composable ItemScope.() -> Unit) // the word "conventional" added to be consistent with `conventionalItems` fun conventionalItem(key: Any? = null, contentType: Any? = null, content: ListItemComponents) @@ -16,7 +17,7 @@ expect class ListScope { count: Int, key: ((index: Int) -> Any)? = null, contentType: (index: Int) -> Any? = { null }, - itemContent: @Composable (index: Int) -> Unit + itemContent: @Composable ItemScope.(index: Int) -> Unit ) // the word "conventional" added to avoid clashing with `items` @@ -28,9 +29,11 @@ expect class ListScope { ) } +expect class ItemScope + class ListItemComponents( val contentModifier: Modifier = Modifier, - val headline: @Composable ((Modifier) -> Unit)? = null, + val headline: @Composable (Modifier) -> Unit, val start: @Composable ((Modifier) -> Unit)? = null, val end: @Composable ((Modifier) -> Unit)? = null, val supportingText: @Composable ((Modifier) -> Unit)? = null, @@ -39,7 +42,7 @@ class ListItemComponents( ) { constructor( contentModifier: Modifier = Modifier, - headline: String? = null, + headline: String, start: Icon? = null, end: Icon? = null, supportingText: String? = null, @@ -47,7 +50,7 @@ class ListItemComponents( overline: String? = null ) : this( contentModifier, - headline.toNullableTextWithModifier(), + headline.toTextWithModifier(), start.toNullableContentWithModifier(), end.toNullableContentWithModifier(), supportingText.toNullableTextWithModifier(), diff --git a/compose-multiplatform-material3/src/jsMain/kotlin/com/huanshankeji/compose/material3/lazy/ext/List.js.kt b/compose-multiplatform-material3/src/jsMain/kotlin/com/huanshankeji/compose/material3/lazy/ext/List.js.kt index 46c0240c..14808a95 100644 --- a/compose-multiplatform-material3/src/jsMain/kotlin/com/huanshankeji/compose/material3/lazy/ext/List.js.kt +++ b/compose-multiplatform-material3/src/jsMain/kotlin/com/huanshankeji/compose/material3/lazy/ext/List.js.kt @@ -14,7 +14,7 @@ import com.varabyte.kobweb.compose.ui.Modifier as PlatformModifier @Composable private fun MdListItemScope.contentFromComponents(listItemComponents: ListItemComponents) = with(listItemComponents) { - headline?.invoke(PlatformModifier.attrsModifier { slot(MdListItemScope.Slot.Headline) }.toCommonModifier()) + headline.invoke(PlatformModifier.attrsModifier { slot(MdListItemScope.Slot.Headline) }.toCommonModifier()) start?.invoke(PlatformModifier.attrsModifier { slot(MdListItemScope.Slot.Start) }.toCommonModifier()) end?.invoke(PlatformModifier.attrsModifier { slot(MdListItemScope.Slot.End) }.toCommonModifier()) supportingText?.invoke( @@ -47,9 +47,9 @@ actual class ListScope(val mdListScope: MdListScope) { actual fun item( key: Any?, contentType: Any?, - content: @Composable () -> Unit + content: @Composable ItemScope.() -> Unit ) = addComposable { - mdListScope.MdListItem { content() } + mdListScope.MdListItem { ItemScope(this).content() } } actual fun conventionalItem( @@ -64,10 +64,10 @@ actual class ListScope(val mdListScope: MdListScope) { count: Int, key: ((index: Int) -> Any)?, contentType: (index: Int) -> Any?, - itemContent: @Composable (index: Int) -> Unit + itemContent: @Composable ItemScope.(index: Int) -> Unit ) = addComposable { repeat(count) { index -> - mdListScope.MdListItem { itemContent(index) } + mdListScope.MdListItem { ItemScope(this).itemContent(index) } } } @@ -83,6 +83,8 @@ actual class ListScope(val mdListScope: MdListScope) { } } +actual class ItemScope(val mdListItemScope: MdListItemScope) + @Composable actual fun List( modifier: Modifier, diff --git a/demo/src/commonMain/kotlin/com/huanshankeji/compose/material/demo/Common.kt b/demo/src/commonMain/kotlin/com/huanshankeji/compose/material/demo/Common.kt index 8d06f420..18cb3a05 100644 --- a/demo/src/commonMain/kotlin/com/huanshankeji/compose/material/demo/Common.kt +++ b/demo/src/commonMain/kotlin/com/huanshankeji/compose/material/demo/Common.kt @@ -61,7 +61,10 @@ fun Common() { var count by remember { mutableStateOf(0) } BasicText("Click to add items to `LazyColumn` and `LazyRow`", Modifier.onClick { count++ }) - val content: LazyListScope.() -> Unit = { items(count) { index -> BasicText("Item $index") } } + val content: LazyListScope.() -> Unit = { + item { BasicText("Item") } + items(count) { index -> BasicText("Item $index") } + } LazyColumn(Modifier.height(listSize), content = content) LazyRow(Modifier.width(listSize), content = content) } diff --git a/demo/src/commonMain/kotlin/com/huanshankeji/compose/material/demo/Material2.kt b/demo/src/commonMain/kotlin/com/huanshankeji/compose/material/demo/Material2.kt index 275fe1ff..ca48fc32 100644 --- a/demo/src/commonMain/kotlin/com/huanshankeji/compose/material/demo/Material2.kt +++ b/demo/src/commonMain/kotlin/com/huanshankeji/compose/material/demo/Material2.kt @@ -3,7 +3,6 @@ package com.huanshankeji.compose.material.demo import androidx.compose.runtime.* import androidx.compose.ui.unit.dp import com.huanshankeji.compose.foundation.background -import com.huanshankeji.compose.foundation.layout.Box import com.huanshankeji.compose.foundation.layout.Column import com.huanshankeji.compose.foundation.layout.Row import com.huanshankeji.compose.foundation.layout.RowScope @@ -22,6 +21,9 @@ import com.huanshankeji.compose.material.icons.filled.Add import com.huanshankeji.compose.material.icons.filled.Menu import com.huanshankeji.compose.material.icons.filled.Search import com.huanshankeji.compose.material.lazy.ext.List +import com.huanshankeji.compose.material.lazy.ext.ListItemComponents +import com.huanshankeji.compose.material.lazy.ext.conventionalItem +import com.huanshankeji.compose.material.lazy.ext.conventionalItems import com.huanshankeji.compose.ui.Modifier import com.huanshankeji.compose.ui.graphics.Color import com.huanshankeji.compose.material.ext.Button as ExtButton @@ -56,23 +58,37 @@ fun Material2() { IconButton(onClick, icon = Icons.Default.Add, contentDescription = "increment count") } - Box(Modifier.padding(16.dp)) { - List(Modifier.height(listSize)) { + val listModifier = Modifier.padding(16.dp).height(listSize) + List(listModifier) { + item { + Text("Ungrouped item") + } + items(count) { + Text("Ungrouped item $it/$count") + } + group(headerContent = { + Text("Group title") + }) { item { - Text("Ungrouped item") + Text("Grouped item") } items(count) { - Text("Ungrouped item $it/$count") + Text("Grouped item $it/$count") } - group(headerContent = { - Text("Group title") - }) { - item { - Text("Grouped item") - } - items(count) { - Text("Grouped item $it/$count") - } + } + } + val secondaryText = "Secondary text" + List(listModifier) { + conventionalItem(content = ListItemComponents("Ungrouped item", secondaryText)) + conventionalItems(count) { + ListItemComponents("Ungrouped item $it/$count", secondaryText) + } + group(headerContent = { + Text("Group title") + }) { + conventionalItem(content = ListItemComponents("Grouped item", secondaryText)) + conventionalItems(count) { + ListItemComponents("Grouped item $it/$count", secondaryText) } } } diff --git a/demo/src/commonMain/kotlin/com/huanshankeji/compose/material/demo/Material3.kt b/demo/src/commonMain/kotlin/com/huanshankeji/compose/material/demo/Material3.kt index 3b4d0b97..3c70a945 100644 --- a/demo/src/commonMain/kotlin/com/huanshankeji/compose/material/demo/Material3.kt +++ b/demo/src/commonMain/kotlin/com/huanshankeji/compose/material/demo/Material3.kt @@ -140,7 +140,7 @@ fun Material3() { Text("Click a button to show the list:") List(Modifier.height(listSize)) { - conventionalItems(count) { index -> + fun content(index: String) = ListItemComponents( Modifier, "Headline $index", @@ -150,6 +150,9 @@ fun Material3() { "Trailing supporting text $index", "Overline $index" ) + conventionalItem(content = content("")) + conventionalItems(count) { index -> + content(index.toString()) } } } From 08a36785dd2a16d11f5f5fa2d166450e877ef7dc Mon Sep 17 00:00:00 2001 From: Shreck Ye Date: Wed, 8 May 2024 00:21:52 +0800 Subject: [PATCH 63/75] Move `Divider` into `Material2` in the demo --- .../kotlin/com/huanshankeji/compose/material/demo/Common.kt | 3 --- .../kotlin/com/huanshankeji/compose/material/demo/Material2.kt | 1 + 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/demo/src/commonMain/kotlin/com/huanshankeji/compose/material/demo/Common.kt b/demo/src/commonMain/kotlin/com/huanshankeji/compose/material/demo/Common.kt index 18cb3a05..f7f3b520 100644 --- a/demo/src/commonMain/kotlin/com/huanshankeji/compose/material/demo/Common.kt +++ b/demo/src/commonMain/kotlin/com/huanshankeji/compose/material/demo/Common.kt @@ -19,7 +19,6 @@ import com.huanshankeji.compose.layout.height import com.huanshankeji.compose.layout.padding import com.huanshankeji.compose.layout.size import com.huanshankeji.compose.layout.width -import com.huanshankeji.compose.material.Divider import com.huanshankeji.compose.ui.Modifier import com.huanshankeji.compose.ui.graphics.Color @@ -42,8 +41,6 @@ fun Common() { ColorBox(Color(1f, 0f, 0f, 0.5f)) } - Divider() - Row { @Composable fun NestedColorBox(modifier: Modifier) = diff --git a/demo/src/commonMain/kotlin/com/huanshankeji/compose/material/demo/Material2.kt b/demo/src/commonMain/kotlin/com/huanshankeji/compose/material/demo/Material2.kt index ca48fc32..858ef626 100644 --- a/demo/src/commonMain/kotlin/com/huanshankeji/compose/material/demo/Material2.kt +++ b/demo/src/commonMain/kotlin/com/huanshankeji/compose/material/demo/Material2.kt @@ -77,6 +77,7 @@ fun Material2() { } } } + Divider() val secondaryText = "Secondary text" List(listModifier) { conventionalItem(content = ListItemComponents("Ungrouped item", secondaryText)) From e42eacff0ba646ff11649384e8f43c63d3db7a93 Mon Sep 17 00:00:00 2001 From: Shreck Ye Date: Wed, 8 May 2024 12:36:43 +0800 Subject: [PATCH 64/75] Simply support the scroll modifiers without supporting `ScrollState` on JS yet and test them in the demo Resolve #19 --- .../foundation/Scroll.androidxCommon.kt | 19 +++++++++++ .../huanshankeji/compose/foundation/Scroll.kt | 29 +++++++++++++++++ .../compose/foundation/Scroll.js.kt | 32 +++++++++++++++++++ .../compose/foundation/ext/css/Scroll.kt | 13 ++++++++ .../compose/foundation/lazy/LazyDsl.js.kt | 32 ++++++++----------- .../compose/material/lazy/ext/LazyDsl.js.kt | 8 ++--- .../compose/material3/lazy/ext/List.js.kt | 8 ++--- .../compose/material/demo/Common.kt | 22 +++++++++---- 8 files changed, 126 insertions(+), 37 deletions(-) create mode 100644 compose-multiplatform-common/src/androidxCommonMain/kotlin/com/huanshankeji/compose/foundation/Scroll.androidxCommon.kt create mode 100644 compose-multiplatform-common/src/commonMain/kotlin/com/huanshankeji/compose/foundation/Scroll.kt create mode 100644 compose-multiplatform-common/src/jsMain/kotlin/com/huanshankeji/compose/foundation/Scroll.js.kt create mode 100644 compose-multiplatform-common/src/jsMain/kotlin/com/huanshankeji/compose/foundation/ext/css/Scroll.kt diff --git a/compose-multiplatform-common/src/androidxCommonMain/kotlin/com/huanshankeji/compose/foundation/Scroll.androidxCommon.kt b/compose-multiplatform-common/src/androidxCommonMain/kotlin/com/huanshankeji/compose/foundation/Scroll.androidxCommon.kt new file mode 100644 index 00000000..068fe97e --- /dev/null +++ b/compose-multiplatform-common/src/androidxCommonMain/kotlin/com/huanshankeji/compose/foundation/Scroll.androidxCommon.kt @@ -0,0 +1,19 @@ +package com.huanshankeji.compose.foundation + +import androidx.compose.foundation.horizontalScroll +import androidx.compose.foundation.rememberScrollState +import androidx.compose.foundation.verticalScroll +import androidx.compose.runtime.Composable +import com.huanshankeji.compose.ui.Modifier + +@Composable +actual fun rememberScrollState(initial: Int): ScrollState = + rememberScrollState(initial) + +actual typealias ScrollState = androidx.compose.foundation.ScrollState + +actual fun Modifier.verticalScroll(state: ScrollState): Modifier = + platformModify { verticalScroll(state) } + +actual fun Modifier.horizontalScroll(state: ScrollState): Modifier = + platformModify { horizontalScroll(state) } diff --git a/compose-multiplatform-common/src/commonMain/kotlin/com/huanshankeji/compose/foundation/Scroll.kt b/compose-multiplatform-common/src/commonMain/kotlin/com/huanshankeji/compose/foundation/Scroll.kt new file mode 100644 index 00000000..e5ca0111 --- /dev/null +++ b/compose-multiplatform-common/src/commonMain/kotlin/com/huanshankeji/compose/foundation/Scroll.kt @@ -0,0 +1,29 @@ +package com.huanshankeji.compose.foundation + +import androidx.compose.runtime.Composable +import androidx.compose.runtime.Stable +import com.huanshankeji.compose.ui.Modifier + +@Composable +expect fun rememberScrollState(initial: Int = 0): ScrollState + +/** + * Not working on JS yet and delegating to [Unit]. + */ +@Stable +expect class ScrollState + +/* +It seems `state` has to be achieved with `DisposableEffect` on JS which can not be set with the Kobweb `Modifier` yet. +See https://developer.mozilla.org/en-US/docs/Web/API/Element/scrollTop. + */ +expect fun Modifier.verticalScroll( + state: ScrollState + /* + enabled: Boolean = true, + flingBehavior: FlingBehavior? = null, + reverseScrolling: Boolean = false + */ +): Modifier + +expect fun Modifier.horizontalScroll(state: ScrollState): Modifier diff --git a/compose-multiplatform-common/src/jsMain/kotlin/com/huanshankeji/compose/foundation/Scroll.js.kt b/compose-multiplatform-common/src/jsMain/kotlin/com/huanshankeji/compose/foundation/Scroll.js.kt new file mode 100644 index 00000000..8c1b3e31 --- /dev/null +++ b/compose-multiplatform-common/src/jsMain/kotlin/com/huanshankeji/compose/foundation/Scroll.js.kt @@ -0,0 +1,32 @@ +package com.huanshankeji.compose.foundation + +import androidx.compose.runtime.Composable +import com.huanshankeji.compose.foundation.ext.css.horizontalScroll +import com.huanshankeji.compose.foundation.ext.css.verticalScroll +import com.huanshankeji.compose.ui.Modifier +import com.varabyte.kobweb.compose.ui.styleModifier +import com.varabyte.kobweb.compose.ui.Modifier as PlatformModifier + +fun PlatformModifier.verticalScroll() = + styleModifier { verticalScroll() } + +fun PlatformModifier.horizontalScroll() = + styleModifier { horizontalScroll() } + +val verticalScrollPlatformModifier = PlatformModifier.verticalScroll() +val horizontalScrollPlatformModifier = PlatformModifier.horizontalScroll() + + +@Composable +actual fun rememberScrollState(initial: Int): ScrollState = + ScrollState + +actual typealias ScrollState = Unit + +actual fun Modifier.verticalScroll(state: ScrollState): Modifier = + platformModify { verticalScroll() } + + +actual fun Modifier.horizontalScroll(state: ScrollState): Modifier = + platformModify { horizontalScroll() } + diff --git a/compose-multiplatform-common/src/jsMain/kotlin/com/huanshankeji/compose/foundation/ext/css/Scroll.kt b/compose-multiplatform-common/src/jsMain/kotlin/com/huanshankeji/compose/foundation/ext/css/Scroll.kt new file mode 100644 index 00000000..9eaca85c --- /dev/null +++ b/compose-multiplatform-common/src/jsMain/kotlin/com/huanshankeji/compose/foundation/ext/css/Scroll.kt @@ -0,0 +1,13 @@ +package com.huanshankeji.compose.foundation.ext.css + +import com.varabyte.kobweb.compose.css.Overflow +import com.varabyte.kobweb.compose.css.overflowX +import com.varabyte.kobweb.compose.css.overflowY +import org.jetbrains.compose.web.css.StyleScope + +fun StyleScope.horizontalScroll() = + overflowX(Overflow.Auto) + +fun StyleScope.verticalScroll() = + //overflowY(Overflow.Scroll) + overflowY(Overflow.Auto) diff --git a/compose-multiplatform-common/src/jsMain/kotlin/com/huanshankeji/compose/foundation/lazy/LazyDsl.js.kt b/compose-multiplatform-common/src/jsMain/kotlin/com/huanshankeji/compose/foundation/lazy/LazyDsl.js.kt index 71047818..73a7e70b 100644 --- a/compose-multiplatform-common/src/jsMain/kotlin/com/huanshankeji/compose/foundation/lazy/LazyDsl.js.kt +++ b/compose-multiplatform-common/src/jsMain/kotlin/com/huanshankeji/compose/foundation/lazy/LazyDsl.js.kt @@ -1,17 +1,15 @@ package com.huanshankeji.compose.foundation.lazy import androidx.compose.runtime.Composable +import com.huanshankeji.compose.foundation.horizontalScrollPlatformModifier import com.huanshankeji.compose.foundation.layout.Arrangement import com.huanshankeji.compose.foundation.layout.Column import com.huanshankeji.compose.foundation.layout.Row +import com.huanshankeji.compose.foundation.verticalScrollPlatformModifier import com.huanshankeji.compose.runtime.DeferredComposableRunner import com.huanshankeji.compose.ui.Alignment import com.huanshankeji.compose.ui.Modifier -import com.varabyte.kobweb.compose.css.Overflow -import com.varabyte.kobweb.compose.css.overflowX -import com.varabyte.kobweb.compose.css.overflowY -import com.varabyte.kobweb.compose.ui.styleModifier -import org.jetbrains.compose.web.css.StyleScope +import com.huanshankeji.compose.ui.toCommonModifier /* @LazyScopeMarker @@ -55,9 +53,11 @@ actual fun LazyRow( verticalAlignment: Alignment.Vertical, content: LazyListScope.() -> Unit ) = - Row(modifier.platformModify { - styleModifier { rowOverflow() } - }, horizontalArrangement, verticalAlignment) { + Row( + horizontalScrollPlatformModifier.then(modifier.platformModifier).toCommonModifier(), + horizontalArrangement, + verticalAlignment + ) { LazyListScope().ComposableRun(content) } @@ -69,16 +69,10 @@ actual fun LazyColumn( horizontalAlignment: Alignment.Horizontal, content: LazyListScope.() -> Unit ) = - Column(modifier.platformModify { - styleModifier { columnOverflow() } - }, verticalArrangement, horizontalAlignment) { + Column( + verticalScrollPlatformModifier.then(modifier.platformModifier).toCommonModifier(), + verticalArrangement, + horizontalAlignment + ) { LazyListScope().ComposableRun(content) } - - -fun StyleScope.rowOverflow() = - overflowX(Overflow.Auto) - -fun StyleScope.columnOverflow() = - //overflowY(Overflow.Scroll) - overflowY(Overflow.Auto) diff --git a/compose-multiplatform-material/src/jsMain/kotlin/com/huanshankeji/compose/material/lazy/ext/LazyDsl.js.kt b/compose-multiplatform-material/src/jsMain/kotlin/com/huanshankeji/compose/material/lazy/ext/LazyDsl.js.kt index 708cdd22..4bd1bdad 100644 --- a/compose-multiplatform-material/src/jsMain/kotlin/com/huanshankeji/compose/material/lazy/ext/LazyDsl.js.kt +++ b/compose-multiplatform-material/src/jsMain/kotlin/com/huanshankeji/compose/material/lazy/ext/LazyDsl.js.kt @@ -1,7 +1,7 @@ package com.huanshankeji.compose.material.lazy.ext import androidx.compose.runtime.Composable -import com.huanshankeji.compose.foundation.lazy.columnOverflow +import com.huanshankeji.compose.foundation.verticalScrollPlatformModifier import com.huanshankeji.compose.runtime.DeferredComposableRunner import com.huanshankeji.compose.ui.Modifier import com.varabyte.kobweb.compose.ui.toAttrs @@ -78,10 +78,6 @@ actual class HeaderScope(val headingElementScope: ElementScope Unit) = - MDCList(attrs = modifier.platformModifier.toAttrs { - style { - columnOverflow() - } - }) { + MDCList(attrs = verticalScrollPlatformModifier.then(modifier.platformModifier).toAttrs()) { ListScope(this).ComposableRun(content) } diff --git a/compose-multiplatform-material3/src/jsMain/kotlin/com/huanshankeji/compose/material3/lazy/ext/List.js.kt b/compose-multiplatform-material3/src/jsMain/kotlin/com/huanshankeji/compose/material3/lazy/ext/List.js.kt index 14808a95..9d0f0b7e 100644 --- a/compose-multiplatform-material3/src/jsMain/kotlin/com/huanshankeji/compose/material3/lazy/ext/List.js.kt +++ b/compose-multiplatform-material3/src/jsMain/kotlin/com/huanshankeji/compose/material3/lazy/ext/List.js.kt @@ -1,7 +1,7 @@ package com.huanshankeji.compose.material3.lazy.ext import androidx.compose.runtime.Composable -import com.huanshankeji.compose.foundation.lazy.columnOverflow +import com.huanshankeji.compose.foundation.verticalScrollPlatformModifier import com.huanshankeji.compose.html.material3.MdList import com.huanshankeji.compose.html.material3.MdListItemScope import com.huanshankeji.compose.html.material3.MdListScope @@ -90,10 +90,6 @@ actual fun List( modifier: Modifier, content: ListScope.() -> Unit ) = - MdList(modifier.platformModifier.toAttrs { - style { - columnOverflow() - } - }) { + MdList(verticalScrollPlatformModifier.then(modifier.platformModifier).toAttrs()) { ListScope(this).ComposableRun(content) } diff --git a/demo/src/commonMain/kotlin/com/huanshankeji/compose/material/demo/Common.kt b/demo/src/commonMain/kotlin/com/huanshankeji/compose/material/demo/Common.kt index f7f3b520..9081523d 100644 --- a/demo/src/commonMain/kotlin/com/huanshankeji/compose/material/demo/Common.kt +++ b/demo/src/commonMain/kotlin/com/huanshankeji/compose/material/demo/Common.kt @@ -2,8 +2,7 @@ package com.huanshankeji.compose.material.demo import androidx.compose.runtime.* import androidx.compose.ui.unit.dp -import com.huanshankeji.compose.foundation.background -import com.huanshankeji.compose.foundation.border +import com.huanshankeji.compose.foundation.* import com.huanshankeji.compose.foundation.ext.outerBorder import com.huanshankeji.compose.foundation.ext.roundedCornerBackgroundAndOuterBorder import com.huanshankeji.compose.foundation.ext.roundedCornerOuterBorder @@ -13,7 +12,6 @@ import com.huanshankeji.compose.foundation.layout.Row import com.huanshankeji.compose.foundation.lazy.LazyColumn import com.huanshankeji.compose.foundation.lazy.LazyListScope import com.huanshankeji.compose.foundation.lazy.LazyRow -import com.huanshankeji.compose.foundation.onClick import com.huanshankeji.compose.foundation.text.BasicText import com.huanshankeji.compose.layout.height import com.huanshankeji.compose.layout.padding @@ -58,11 +56,23 @@ fun Common() { var count by remember { mutableStateOf(0) } BasicText("Click to add items to `LazyColumn` and `LazyRow`", Modifier.onClick { count++ }) - val content: LazyListScope.() -> Unit = { + val lazyListContent: LazyListScope.() -> Unit = { item { BasicText("Item") } items(count) { index -> BasicText("Item $index") } } - LazyColumn(Modifier.height(listSize), content = content) - LazyRow(Modifier.width(listSize), content = content) + LazyColumn(Modifier.height(listSize), content = lazyListContent) + LazyRow(Modifier.width(listSize), content = lazyListContent) + + @Composable + fun ColumnOrRowContent() { + BasicText("Item") + repeat(count) { index -> BasicText("Item $index") } + } + Column(Modifier.height(listSize).verticalScroll(rememberScrollState())) { + ColumnOrRowContent() + } + Row(Modifier.width(listSize).horizontalScroll(rememberScrollState())) { + ColumnOrRowContent() + } } } \ No newline at end of file From 1bb10a2a66769f12ab7159e5ed522761cb32bbe4 Mon Sep 17 00:00:00 2001 From: Shreck Ye Date: Wed, 8 May 2024 21:57:40 +0800 Subject: [PATCH 65/75] Suppress the "'expect'/'actual' classes" warning and try resolving "actual and its non-final expect class must declare exactly the same non-private members" It's unclear to me how to completely resolve the latter problem. For example in `Modifier`, a member `platformModifier` contains a reference to another 'expect'/'actual' type `PlatformModifier` anyway, and so this problem goes on recursively. --- buildSrc/src/main/kotlin/common-conventions.gradle.kts | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/buildSrc/src/main/kotlin/common-conventions.gradle.kts b/buildSrc/src/main/kotlin/common-conventions.gradle.kts index 9f468689..33fca5d7 100644 --- a/buildSrc/src/main/kotlin/common-conventions.gradle.kts +++ b/buildSrc/src/main/kotlin/common-conventions.gradle.kts @@ -1,3 +1,4 @@ +import org.jetbrains.kotlin.gradle.ExperimentalKotlinGradlePluginApi import org.jetbrains.kotlin.gradle.targets.js.dsl.ExperimentalWasmDsl plugins { @@ -35,4 +36,10 @@ kotlin { // for JS and HTML wrappers js() + + + @OptIn(ExperimentalKotlinGradlePluginApi::class) + compilerOptions { + freeCompilerArgs.add("-Xexpect-actual-classes") + } } From 9df10d6532454d91d9d414cc075195572f2b8df6 Mon Sep 17 00:00:00 2001 From: Shreck Ye Date: Wed, 8 May 2024 22:06:43 +0800 Subject: [PATCH 66/75] Add the `PlatformModifier` typealiases Resolve #22 --- .../com/huanshankeji/compose/ui/Modifier.androidxCommon.kt | 3 ++- .../kotlin/com/huanshankeji/compose/foundation/Scroll.js.kt | 2 +- .../com/huanshankeji/compose/foundation/layout/Box.js.kt | 2 +- .../com/huanshankeji/compose/foundation/layout/Column.js.kt | 2 +- .../com/huanshankeji/compose/foundation/layout/Row.js.kt | 2 +- .../jsMain/kotlin/com/huanshankeji/compose/ui/Modifier.js.kt | 3 ++- .../huanshankeji/compose/material/ext/Radio.androidxCommon.kt | 2 +- .../jsMain/kotlin/com/huanshankeji/compose/material/Card.js.kt | 2 +- .../huanshankeji/compose/material3/FloatingActionButton.js.kt | 2 +- .../kotlin/com/huanshankeji/compose/material3/IconButton.js.kt | 2 +- .../kotlin/com/huanshankeji/compose/material3/ext/Button.js.kt | 2 +- .../com/huanshankeji/compose/material3/ext/TextField.js.kt | 2 +- .../com/huanshankeji/compose/material3/lazy/ext/List.js.kt | 2 +- 13 files changed, 15 insertions(+), 13 deletions(-) diff --git a/compose-multiplatform-common/src/androidxCommonMain/kotlin/com/huanshankeji/compose/ui/Modifier.androidxCommon.kt b/compose-multiplatform-common/src/androidxCommonMain/kotlin/com/huanshankeji/compose/ui/Modifier.androidxCommon.kt index 3473e60d..6eed0153 100644 --- a/compose-multiplatform-common/src/androidxCommonMain/kotlin/com/huanshankeji/compose/ui/Modifier.androidxCommon.kt +++ b/compose-multiplatform-common/src/androidxCommonMain/kotlin/com/huanshankeji/compose/ui/Modifier.androidxCommon.kt @@ -3,8 +3,9 @@ package com.huanshankeji.compose.ui import kotlin.jvm.JvmInline import androidx.compose.ui.Modifier as PlatformModifier -//actual typealias Modifier = androidx.compose.ui.Modifier // this doesn't work +typealias PlatformModifier = PlatformModifier +//actual typealias Modifier = androidx.compose.ui.Modifier // this doesn't work actual interface Modifier { val platformModifier: PlatformModifier diff --git a/compose-multiplatform-common/src/jsMain/kotlin/com/huanshankeji/compose/foundation/Scroll.js.kt b/compose-multiplatform-common/src/jsMain/kotlin/com/huanshankeji/compose/foundation/Scroll.js.kt index 8c1b3e31..4e8a12b7 100644 --- a/compose-multiplatform-common/src/jsMain/kotlin/com/huanshankeji/compose/foundation/Scroll.js.kt +++ b/compose-multiplatform-common/src/jsMain/kotlin/com/huanshankeji/compose/foundation/Scroll.js.kt @@ -4,8 +4,8 @@ import androidx.compose.runtime.Composable import com.huanshankeji.compose.foundation.ext.css.horizontalScroll import com.huanshankeji.compose.foundation.ext.css.verticalScroll import com.huanshankeji.compose.ui.Modifier +import com.huanshankeji.compose.ui.PlatformModifier import com.varabyte.kobweb.compose.ui.styleModifier -import com.varabyte.kobweb.compose.ui.Modifier as PlatformModifier fun PlatformModifier.verticalScroll() = styleModifier { verticalScroll() } diff --git a/compose-multiplatform-common/src/jsMain/kotlin/com/huanshankeji/compose/foundation/layout/Box.js.kt b/compose-multiplatform-common/src/jsMain/kotlin/com/huanshankeji/compose/foundation/layout/Box.js.kt index 8035d663..57dc24cf 100644 --- a/compose-multiplatform-common/src/jsMain/kotlin/com/huanshankeji/compose/foundation/layout/Box.js.kt +++ b/compose-multiplatform-common/src/jsMain/kotlin/com/huanshankeji/compose/foundation/layout/Box.js.kt @@ -5,11 +5,11 @@ import androidx.compose.runtime.Immutable import androidx.compose.runtime.Stable import com.huanshankeji.compose.ui.Alignment import com.huanshankeji.compose.ui.Modifier +import com.huanshankeji.compose.ui.PlatformModifier import com.huanshankeji.kobweb.compose.ui.modifiers.sizeFitContent import com.varabyte.kobweb.compose.foundation.layout.LayoutScopeMarker import com.varabyte.kobweb.compose.foundation.layout.Box as PlatformBox import com.varabyte.kobweb.compose.foundation.layout.BoxScope as PlatformBoxScope -import com.varabyte.kobweb.compose.ui.Modifier as PlatformModifier @Composable actual fun Box( diff --git a/compose-multiplatform-common/src/jsMain/kotlin/com/huanshankeji/compose/foundation/layout/Column.js.kt b/compose-multiplatform-common/src/jsMain/kotlin/com/huanshankeji/compose/foundation/layout/Column.js.kt index 9e3b8a6f..2f4996ec 100644 --- a/compose-multiplatform-common/src/jsMain/kotlin/com/huanshankeji/compose/foundation/layout/Column.js.kt +++ b/compose-multiplatform-common/src/jsMain/kotlin/com/huanshankeji/compose/foundation/layout/Column.js.kt @@ -5,10 +5,10 @@ import androidx.compose.runtime.Composable import androidx.compose.runtime.Stable import com.huanshankeji.compose.ui.Alignment import com.huanshankeji.compose.ui.Modifier +import com.huanshankeji.compose.ui.PlatformModifier import com.huanshankeji.kobweb.compose.ui.modifiers.sizeFitContent import com.varabyte.kobweb.compose.foundation.layout.LayoutScopeMarker import com.varabyte.kobweb.compose.foundation.layout.ColumnScope as PlatformColumnScope -import com.varabyte.kobweb.compose.ui.Modifier as PlatformModifier @Composable actual fun Column( diff --git a/compose-multiplatform-common/src/jsMain/kotlin/com/huanshankeji/compose/foundation/layout/Row.js.kt b/compose-multiplatform-common/src/jsMain/kotlin/com/huanshankeji/compose/foundation/layout/Row.js.kt index 36a61e38..2b4b1e9d 100644 --- a/compose-multiplatform-common/src/jsMain/kotlin/com/huanshankeji/compose/foundation/layout/Row.js.kt +++ b/compose-multiplatform-common/src/jsMain/kotlin/com/huanshankeji/compose/foundation/layout/Row.js.kt @@ -5,10 +5,10 @@ import androidx.compose.runtime.Composable import androidx.compose.runtime.Stable import com.huanshankeji.compose.ui.Alignment import com.huanshankeji.compose.ui.Modifier +import com.huanshankeji.compose.ui.PlatformModifier import com.huanshankeji.kobweb.compose.ui.modifiers.sizeFitContent import com.varabyte.kobweb.compose.foundation.layout.LayoutScopeMarker import com.varabyte.kobweb.compose.foundation.layout.RowScope as PlatformRowScope -import com.varabyte.kobweb.compose.ui.Modifier as PlatformModifier @Composable actual fun Row( diff --git a/compose-multiplatform-common/src/jsMain/kotlin/com/huanshankeji/compose/ui/Modifier.js.kt b/compose-multiplatform-common/src/jsMain/kotlin/com/huanshankeji/compose/ui/Modifier.js.kt index f2878068..a4507fc2 100644 --- a/compose-multiplatform-common/src/jsMain/kotlin/com/huanshankeji/compose/ui/Modifier.js.kt +++ b/compose-multiplatform-common/src/jsMain/kotlin/com/huanshankeji/compose/ui/Modifier.js.kt @@ -2,8 +2,9 @@ package com.huanshankeji.compose.ui import com.varabyte.kobweb.compose.ui.Modifier as PlatformModifier -//actual typealias Modifier = com.varabyte.kobweb.compose.ui.Modifier // this doesn't work +typealias PlatformModifier = PlatformModifier +//actual typealias Modifier = com.varabyte.kobweb.compose.ui.Modifier // this doesn't work actual interface Modifier { val platformModifier: PlatformModifier diff --git a/compose-multiplatform-material/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material/ext/Radio.androidxCommon.kt b/compose-multiplatform-material/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material/ext/Radio.androidxCommon.kt index e66dfde7..4376c23a 100644 --- a/compose-multiplatform-material/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material/ext/Radio.androidxCommon.kt +++ b/compose-multiplatform-material/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material/ext/Radio.androidxCommon.kt @@ -8,7 +8,7 @@ import androidx.compose.material.Text import androidx.compose.runtime.Composable import androidx.compose.ui.semantics.Role import com.huanshankeji.compose.ui.Modifier -import androidx.compose.ui.Modifier as PlatformModifier +import com.huanshankeji.compose.ui.PlatformModifier // https://developer.android.com/reference/kotlin/androidx/compose/material/package-summary#RadioButton(kotlin.Boolean,kotlin.Function0,androidx.compose.ui.Modifier,kotlin.Boolean,androidx.compose.foundation.interaction.MutableInteractionSource,androidx.compose.material.RadioButtonColors) diff --git a/compose-multiplatform-material/src/jsMain/kotlin/com/huanshankeji/compose/material/Card.js.kt b/compose-multiplatform-material/src/jsMain/kotlin/com/huanshankeji/compose/material/Card.js.kt index 2f60b7a3..f5b369cd 100644 --- a/compose-multiplatform-material/src/jsMain/kotlin/com/huanshankeji/compose/material/Card.js.kt +++ b/compose-multiplatform-material/src/jsMain/kotlin/com/huanshankeji/compose/material/Card.js.kt @@ -2,10 +2,10 @@ package com.huanshankeji.compose.material import androidx.compose.runtime.Composable import com.huanshankeji.compose.ui.Modifier +import com.huanshankeji.compose.ui.PlatformModifier import com.huanshankeji.kobweb.compose.ui.modifiers.sizeFitContent import com.varabyte.kobweb.compose.ui.toAttrs import dev.petuska.kmdc.card.MDCCard -import com.varabyte.kobweb.compose.ui.Modifier as PlatformModifier @Composable actual fun Card(modifier: Modifier, content: @Composable () -> Unit) = diff --git a/compose-multiplatform-material3/src/jsMain/kotlin/com/huanshankeji/compose/material3/FloatingActionButton.js.kt b/compose-multiplatform-material3/src/jsMain/kotlin/com/huanshankeji/compose/material3/FloatingActionButton.js.kt index 6565312d..fc27c16f 100644 --- a/compose-multiplatform-material3/src/jsMain/kotlin/com/huanshankeji/compose/material3/FloatingActionButton.js.kt +++ b/compose-multiplatform-material3/src/jsMain/kotlin/com/huanshankeji/compose/material3/FloatingActionButton.js.kt @@ -7,9 +7,9 @@ import com.huanshankeji.compose.foundation.layout.RowScope import com.huanshankeji.compose.html.material3.MdFab import com.huanshankeji.compose.html.material3.MdFabScope import com.huanshankeji.compose.ui.Modifier +import com.huanshankeji.compose.ui.PlatformModifier import com.huanshankeji.compose.ui.toCommonModifier import com.varabyte.kobweb.compose.ui.attrsModifier -import com.varabyte.kobweb.compose.ui.Modifier as PlatformModifier internal val MdFabScope.slotEqIconModifier get() = PlatformModifier.attrsModifier { slotEqIcon() }.toCommonModifier() diff --git a/compose-multiplatform-material3/src/jsMain/kotlin/com/huanshankeji/compose/material3/IconButton.js.kt b/compose-multiplatform-material3/src/jsMain/kotlin/com/huanshankeji/compose/material3/IconButton.js.kt index 4dc13be9..b997c461 100644 --- a/compose-multiplatform-material3/src/jsMain/kotlin/com/huanshankeji/compose/material3/IconButton.js.kt +++ b/compose-multiplatform-material3/src/jsMain/kotlin/com/huanshankeji/compose/material3/IconButton.js.kt @@ -4,6 +4,7 @@ import androidx.compose.runtime.Composable import com.huanshankeji.compose.foundation.layout.Box import com.huanshankeji.compose.html.material3.* import com.huanshankeji.compose.ui.Modifier +import com.huanshankeji.compose.ui.PlatformModifier import com.huanshankeji.compose.ui.toCommonModifier import com.huanshankeji.compose.web.attributes.ext.onInput import com.huanshankeji.compose.web.attributes.isFalseOrNull @@ -12,7 +13,6 @@ import com.varabyte.kobweb.compose.ui.attrsModifier import com.varabyte.kobweb.compose.ui.toAttrs import org.jetbrains.compose.web.attributes.AttrsScope import org.w3c.dom.HTMLElement -import com.varabyte.kobweb.compose.ui.Modifier as PlatformModifier internal fun Modifier.toCommonIconToggleButtonAttrs( checked: Boolean, onCheckedChange: (Boolean) -> Unit diff --git a/compose-multiplatform-material3/src/jsMain/kotlin/com/huanshankeji/compose/material3/ext/Button.js.kt b/compose-multiplatform-material3/src/jsMain/kotlin/com/huanshankeji/compose/material3/ext/Button.js.kt index 77029b55..6f186725 100644 --- a/compose-multiplatform-material3/src/jsMain/kotlin/com/huanshankeji/compose/material3/ext/Button.js.kt +++ b/compose-multiplatform-material3/src/jsMain/kotlin/com/huanshankeji/compose/material3/ext/Button.js.kt @@ -4,9 +4,9 @@ import androidx.compose.runtime.Composable import com.huanshankeji.compose.html.material3.MdButtonScope import com.huanshankeji.compose.material3.* import com.huanshankeji.compose.ui.Modifier +import com.huanshankeji.compose.ui.PlatformModifier import com.huanshankeji.compose.ui.toCommonModifier import com.varabyte.kobweb.compose.ui.attrsModifier -import com.varabyte.kobweb.compose.ui.Modifier as PlatformModifier private fun (@Composable () -> Unit).toMdButtonScopeContent( icon: @Composable ((Modifier) -> Unit)? diff --git a/compose-multiplatform-material3/src/jsMain/kotlin/com/huanshankeji/compose/material3/ext/TextField.js.kt b/compose-multiplatform-material3/src/jsMain/kotlin/com/huanshankeji/compose/material3/ext/TextField.js.kt index 18f41368..6bb9cd81 100644 --- a/compose-multiplatform-material3/src/jsMain/kotlin/com/huanshankeji/compose/material3/ext/TextField.js.kt +++ b/compose-multiplatform-material3/src/jsMain/kotlin/com/huanshankeji/compose/material3/ext/TextField.js.kt @@ -9,6 +9,7 @@ import com.huanshankeji.compose.html.material3.MdFilledTextField import com.huanshankeji.compose.html.material3.MdOutlinedTextField import com.huanshankeji.compose.html.material3.MdTextFieldScope import com.huanshankeji.compose.ui.Modifier +import com.huanshankeji.compose.ui.PlatformModifier import com.huanshankeji.compose.ui.toCommonModifier import com.huanshankeji.compose.web.attributes.ext.onInput import com.huanshankeji.compose.web.attributes.isFalseOrNull @@ -18,7 +19,6 @@ import com.varabyte.kobweb.compose.ui.attrsModifier import com.varabyte.kobweb.compose.ui.toAttrs import org.jetbrains.compose.web.attributes.AttrsScope import org.w3c.dom.HTMLElement -import com.varabyte.kobweb.compose.ui.Modifier as PlatformModifier private fun Modifier.toTextFieldAttrs( onValueChange: (String) -> Unit, keyboardOptions: KeyboardOptions, keyboardActions: KeyboardActions, diff --git a/compose-multiplatform-material3/src/jsMain/kotlin/com/huanshankeji/compose/material3/lazy/ext/List.js.kt b/compose-multiplatform-material3/src/jsMain/kotlin/com/huanshankeji/compose/material3/lazy/ext/List.js.kt index 9d0f0b7e..c102ae2d 100644 --- a/compose-multiplatform-material3/src/jsMain/kotlin/com/huanshankeji/compose/material3/lazy/ext/List.js.kt +++ b/compose-multiplatform-material3/src/jsMain/kotlin/com/huanshankeji/compose/material3/lazy/ext/List.js.kt @@ -7,10 +7,10 @@ import com.huanshankeji.compose.html.material3.MdListItemScope import com.huanshankeji.compose.html.material3.MdListScope import com.huanshankeji.compose.runtime.DeferredComposableRunner import com.huanshankeji.compose.ui.Modifier +import com.huanshankeji.compose.ui.PlatformModifier import com.huanshankeji.compose.ui.toCommonModifier import com.varabyte.kobweb.compose.ui.attrsModifier import com.varabyte.kobweb.compose.ui.toAttrs -import com.varabyte.kobweb.compose.ui.Modifier as PlatformModifier @Composable private fun MdListItemScope.contentFromComponents(listItemComponents: ListItemComponents) = with(listItemComponents) { From cd7fdf316a3b5e90283f2a505c1e2bd27a378f4e Mon Sep 17 00:00:00 2001 From: Shreck Ye Date: Wed, 8 May 2024 22:28:15 +0800 Subject: [PATCH 67/75] Rename the Material 2 module's name and package to `material2` explicitly Resolve #21 --- .../build.gradle.kts | 0 .../compose/material2}/Button.androidxCommon.kt | 2 +- .../compose/material2}/Card.androidxCommon.kt | 2 +- .../compose/material2}/Checkbox.androidxCommon.kt | 2 +- .../compose/material2}/Divider.androidxCommon.kt | 2 +- .../compose/material2}/Icon.androidxCommon.kt | 2 +- .../material2}/IconButton.androidxCommon.kt | 2 +- .../compose/material2}/Switch.androidxCommon.kt | 2 +- .../compose/material2}/Text.androidxCommon.kt | 2 +- .../material2}/ext/Button.androidxCommon.kt | 4 ++-- .../compose/material2}/ext/Radio.androidxCommon.kt | 2 +- .../material2}/ext/Switch.androidxCommon.kt | 4 ++-- .../compose/material2}/ext/Text.androidxCommon.kt | 2 +- .../material2}/ext/TextField.androidxCommon.kt | 6 +++--- .../ext/TopAppBarScaffold.androidxCommon.kt | 6 +++--- .../material2}/lazy/ext/LazyDsl.androidxCommon.kt | 2 +- .../com/huanshankeji/compose/material2}/Button.kt | 2 +- .../com/huanshankeji/compose/material2}/Card.kt | 2 +- .../huanshankeji/compose/material2}/Checkbox.kt | 2 +- .../com/huanshankeji/compose/material2}/Divider.kt | 2 +- .../com/huanshankeji/compose/material2}/Icon.kt | 2 +- .../huanshankeji/compose/material2}/IconButton.kt | 2 +- .../com/huanshankeji/compose/material2}/Switch.kt | 2 +- .../com/huanshankeji/compose/material2}/Text.kt | 4 ++-- .../huanshankeji/compose/material2}/ext/Button.kt | 2 +- .../compose/material2}/ext/IconButton.kt | 6 +++--- .../huanshankeji/compose/material2}/ext/Radio.kt | 2 +- .../huanshankeji/compose/material2}/ext/Switch.kt | 2 +- .../huanshankeji/compose/material2}/ext/Text.kt | 4 ++-- .../compose/material2}/ext/TextField.kt | 2 +- .../compose/material2}/ext/TopAppBarScaffold.kt | 2 +- .../compose/material2}/lazy/ext/LazyDsl.kt | 4 ++-- .../huanshankeji/compose/material2}/Button.js.kt | 6 +++--- .../com/huanshankeji/compose/material2}/Card.js.kt | 2 +- .../huanshankeji/compose/material2}/Checkbox.js.kt | 2 +- .../huanshankeji/compose/material2}/Divider.js.kt | 2 +- .../com/huanshankeji/compose/material2}/Icon.js.kt | 4 ++-- .../compose/material2}/IconButton.js.kt | 2 +- .../huanshankeji/compose/material2}/Switch.js.kt | 2 +- .../com/huanshankeji/compose/material2}/Text.js.kt | 2 +- .../compose/material2}/ext/Button.js.kt | 6 +++--- .../compose/material2}/ext/Radio.js.kt | 2 +- .../compose/material2}/ext/Switch.js.kt | 4 ++-- .../huanshankeji/compose/material2}/ext/Text.js.kt | 2 +- .../compose/material2}/ext/TextField.js.kt | 2 +- .../compose/material2}/ext/TopAppBarScaffold.js.kt | 2 +- .../compose/material2}/icons/IconsMdc.kt | 3 ++- .../compose/material2}/lazy/ext/LazyDsl.js.kt | 2 +- demo/build.gradle.kts | 2 +- .../compose/material/demo/Material2.kt | 14 +++++++------- settings.gradle.kts | 2 +- 51 files changed, 74 insertions(+), 73 deletions(-) rename {compose-multiplatform-material => compose-multiplatform-material2}/build.gradle.kts (100%) rename {compose-multiplatform-material/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material => compose-multiplatform-material2/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material2}/Button.androidxCommon.kt (96%) rename {compose-multiplatform-material/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material => compose-multiplatform-material2/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material2}/Card.androidxCommon.kt (85%) rename {compose-multiplatform-material/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material => compose-multiplatform-material2/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material2}/Checkbox.androidxCommon.kt (88%) rename {compose-multiplatform-material/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material => compose-multiplatform-material2/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material2}/Divider.androidxCommon.kt (82%) rename {compose-multiplatform-material/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material => compose-multiplatform-material2/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material2}/Icon.androidxCommon.kt (88%) rename {compose-multiplatform-material/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material => compose-multiplatform-material2/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material2}/IconButton.androidxCommon.kt (93%) rename {compose-multiplatform-material/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material => compose-multiplatform-material2/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material2}/Switch.androidxCommon.kt (90%) rename {compose-multiplatform-material/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material => compose-multiplatform-material2/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material2}/Text.androidxCommon.kt (83%) rename {compose-multiplatform-material/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material => compose-multiplatform-material2/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material2}/ext/Button.androidxCommon.kt (90%) rename {compose-multiplatform-material/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material => compose-multiplatform-material2/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material2}/ext/Radio.androidxCommon.kt (96%) rename {compose-multiplatform-material/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material => compose-multiplatform-material2/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material2}/ext/Switch.androidxCommon.kt (82%) rename {compose-multiplatform-material/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material => compose-multiplatform-material2/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material2}/ext/Text.androidxCommon.kt (75%) rename {compose-multiplatform-material/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material => compose-multiplatform-material2/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material2}/ext/TextField.androidxCommon.kt (96%) rename {compose-multiplatform-material/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material => compose-multiplatform-material2/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material2}/ext/TopAppBarScaffold.androidxCommon.kt (91%) rename {compose-multiplatform-material/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material => compose-multiplatform-material2/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material2}/lazy/ext/LazyDsl.androidxCommon.kt (97%) rename {compose-multiplatform-material/src/commonMain/kotlin/com/huanshankeji/compose/material => compose-multiplatform-material2/src/commonMain/kotlin/com/huanshankeji/compose/material2}/Button.kt (93%) rename {compose-multiplatform-material/src/commonMain/kotlin/com/huanshankeji/compose/material => compose-multiplatform-material2/src/commonMain/kotlin/com/huanshankeji/compose/material2}/Card.kt (88%) rename {compose-multiplatform-material/src/commonMain/kotlin/com/huanshankeji/compose/material => compose-multiplatform-material2/src/commonMain/kotlin/com/huanshankeji/compose/material2}/Checkbox.kt (85%) rename {compose-multiplatform-material/src/commonMain/kotlin/com/huanshankeji/compose/material => compose-multiplatform-material2/src/commonMain/kotlin/com/huanshankeji/compose/material2}/Divider.kt (84%) rename {compose-multiplatform-material/src/commonMain/kotlin/com/huanshankeji/compose/material => compose-multiplatform-material2/src/commonMain/kotlin/com/huanshankeji/compose/material2}/Icon.kt (85%) rename {compose-multiplatform-material/src/commonMain/kotlin/com/huanshankeji/compose/material => compose-multiplatform-material2/src/commonMain/kotlin/com/huanshankeji/compose/material2}/IconButton.kt (90%) rename {compose-multiplatform-material/src/commonMain/kotlin/com/huanshankeji/compose/material => compose-multiplatform-material2/src/commonMain/kotlin/com/huanshankeji/compose/material2}/Switch.kt (85%) rename {compose-multiplatform-material/src/commonMain/kotlin/com/huanshankeji/compose/material => compose-multiplatform-material2/src/commonMain/kotlin/com/huanshankeji/compose/material2}/Text.kt (84%) rename {compose-multiplatform-material/src/commonMain/kotlin/com/huanshankeji/compose/material => compose-multiplatform-material2/src/commonMain/kotlin/com/huanshankeji/compose/material2}/ext/Button.kt (89%) rename {compose-multiplatform-material/src/commonMain/kotlin/com/huanshankeji/compose/material => compose-multiplatform-material2/src/commonMain/kotlin/com/huanshankeji/compose/material2}/ext/IconButton.kt (58%) rename {compose-multiplatform-material/src/commonMain/kotlin/com/huanshankeji/compose/material => compose-multiplatform-material2/src/commonMain/kotlin/com/huanshankeji/compose/material2}/ext/Radio.kt (89%) rename {compose-multiplatform-material/src/commonMain/kotlin/com/huanshankeji/compose/material => compose-multiplatform-material2/src/commonMain/kotlin/com/huanshankeji/compose/material2}/ext/Switch.kt (85%) rename {compose-multiplatform-material/src/commonMain/kotlin/com/huanshankeji/compose/material => compose-multiplatform-material2/src/commonMain/kotlin/com/huanshankeji/compose/material2}/ext/Text.kt (82%) rename {compose-multiplatform-material/src/commonMain/kotlin/com/huanshankeji/compose/material => compose-multiplatform-material2/src/commonMain/kotlin/com/huanshankeji/compose/material2}/ext/TextField.kt (98%) rename {compose-multiplatform-material/src/commonMain/kotlin/com/huanshankeji/compose/material => compose-multiplatform-material2/src/commonMain/kotlin/com/huanshankeji/compose/material2}/ext/TopAppBarScaffold.kt (95%) rename {compose-multiplatform-material/src/commonMain/kotlin/com/huanshankeji/compose/material => compose-multiplatform-material2/src/commonMain/kotlin/com/huanshankeji/compose/material2}/lazy/ext/LazyDsl.kt (94%) rename {compose-multiplatform-material/src/jsMain/kotlin/com/huanshankeji/compose/material => compose-multiplatform-material2/src/jsMain/kotlin/com/huanshankeji/compose/material2}/Button.js.kt (90%) rename {compose-multiplatform-material/src/jsMain/kotlin/com/huanshankeji/compose/material => compose-multiplatform-material2/src/jsMain/kotlin/com/huanshankeji/compose/material2}/Card.js.kt (91%) rename {compose-multiplatform-material/src/jsMain/kotlin/com/huanshankeji/compose/material => compose-multiplatform-material2/src/jsMain/kotlin/com/huanshankeji/compose/material2}/Checkbox.js.kt (92%) rename {compose-multiplatform-material/src/jsMain/kotlin/com/huanshankeji/compose/material => compose-multiplatform-material2/src/jsMain/kotlin/com/huanshankeji/compose/material2}/Divider.js.kt (93%) rename {compose-multiplatform-material/src/jsMain/kotlin/com/huanshankeji/compose/material => compose-multiplatform-material2/src/jsMain/kotlin/com/huanshankeji/compose/material2}/Icon.js.kt (86%) rename {compose-multiplatform-material/src/jsMain/kotlin/com/huanshankeji/compose/material => compose-multiplatform-material2/src/jsMain/kotlin/com/huanshankeji/compose/material2}/IconButton.js.kt (93%) rename {compose-multiplatform-material/src/jsMain/kotlin/com/huanshankeji/compose/material => compose-multiplatform-material2/src/jsMain/kotlin/com/huanshankeji/compose/material2}/Switch.js.kt (95%) rename {compose-multiplatform-material/src/jsMain/kotlin/com/huanshankeji/compose/material => compose-multiplatform-material2/src/jsMain/kotlin/com/huanshankeji/compose/material2}/Text.js.kt (84%) rename {compose-multiplatform-material/src/jsMain/kotlin/com/huanshankeji/compose/material => compose-multiplatform-material2/src/jsMain/kotlin/com/huanshankeji/compose/material2}/ext/Button.js.kt (84%) rename {compose-multiplatform-material/src/jsMain/kotlin/com/huanshankeji/compose/material => compose-multiplatform-material2/src/jsMain/kotlin/com/huanshankeji/compose/material2}/ext/Radio.js.kt (94%) rename {compose-multiplatform-material/src/jsMain/kotlin/com/huanshankeji/compose/material => compose-multiplatform-material2/src/jsMain/kotlin/com/huanshankeji/compose/material2}/ext/Switch.js.kt (76%) rename {compose-multiplatform-material/src/jsMain/kotlin/com/huanshankeji/compose/material => compose-multiplatform-material2/src/jsMain/kotlin/com/huanshankeji/compose/material2}/ext/Text.js.kt (76%) rename {compose-multiplatform-material/src/jsMain/kotlin/com/huanshankeji/compose/material => compose-multiplatform-material2/src/jsMain/kotlin/com/huanshankeji/compose/material2}/ext/TextField.js.kt (99%) rename {compose-multiplatform-material/src/jsMain/kotlin/com/huanshankeji/compose/material => compose-multiplatform-material2/src/jsMain/kotlin/com/huanshankeji/compose/material2}/ext/TopAppBarScaffold.js.kt (98%) rename {compose-multiplatform-material/src/jsMain/kotlin/com/huanshankeji/compose/material => compose-multiplatform-material2/src/jsMain/kotlin/com/huanshankeji/compose/material2}/icons/IconsMdc.kt (60%) rename {compose-multiplatform-material/src/jsMain/kotlin/com/huanshankeji/compose/material => compose-multiplatform-material2/src/jsMain/kotlin/com/huanshankeji/compose/material2}/lazy/ext/LazyDsl.js.kt (98%) diff --git a/compose-multiplatform-material/build.gradle.kts b/compose-multiplatform-material2/build.gradle.kts similarity index 100% rename from compose-multiplatform-material/build.gradle.kts rename to compose-multiplatform-material2/build.gradle.kts diff --git a/compose-multiplatform-material/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material/Button.androidxCommon.kt b/compose-multiplatform-material2/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material2/Button.androidxCommon.kt similarity index 96% rename from compose-multiplatform-material/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material/Button.androidxCommon.kt rename to compose-multiplatform-material2/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material2/Button.androidxCommon.kt index 97e9cb74..523b3632 100644 --- a/compose-multiplatform-material/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material/Button.androidxCommon.kt +++ b/compose-multiplatform-material2/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material2/Button.androidxCommon.kt @@ -1,4 +1,4 @@ -package com.huanshankeji.compose.material +package com.huanshankeji.compose.material2 import androidx.compose.runtime.Composable import com.huanshankeji.compose.foundation.layout.RowScope diff --git a/compose-multiplatform-material/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material/Card.androidxCommon.kt b/compose-multiplatform-material2/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material2/Card.androidxCommon.kt similarity index 85% rename from compose-multiplatform-material/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material/Card.androidxCommon.kt rename to compose-multiplatform-material2/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material2/Card.androidxCommon.kt index f7ce91f1..43743737 100644 --- a/compose-multiplatform-material/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material/Card.androidxCommon.kt +++ b/compose-multiplatform-material2/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material2/Card.androidxCommon.kt @@ -1,4 +1,4 @@ -package com.huanshankeji.compose.material +package com.huanshankeji.compose.material2 import androidx.compose.runtime.Composable import com.huanshankeji.compose.ui.Modifier diff --git a/compose-multiplatform-material/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material/Checkbox.androidxCommon.kt b/compose-multiplatform-material2/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material2/Checkbox.androidxCommon.kt similarity index 88% rename from compose-multiplatform-material/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material/Checkbox.androidxCommon.kt rename to compose-multiplatform-material2/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material2/Checkbox.androidxCommon.kt index afc32fca..76dfdb69 100644 --- a/compose-multiplatform-material/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material/Checkbox.androidxCommon.kt +++ b/compose-multiplatform-material2/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material2/Checkbox.androidxCommon.kt @@ -1,4 +1,4 @@ -package com.huanshankeji.compose.material +package com.huanshankeji.compose.material2 import androidx.compose.runtime.Composable import com.huanshankeji.compose.ui.Modifier diff --git a/compose-multiplatform-material/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material/Divider.androidxCommon.kt b/compose-multiplatform-material2/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material2/Divider.androidxCommon.kt similarity index 82% rename from compose-multiplatform-material/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material/Divider.androidxCommon.kt rename to compose-multiplatform-material2/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material2/Divider.androidxCommon.kt index 92ac8ecd..cde8267c 100644 --- a/compose-multiplatform-material/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material/Divider.androidxCommon.kt +++ b/compose-multiplatform-material2/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material2/Divider.androidxCommon.kt @@ -1,4 +1,4 @@ -package com.huanshankeji.compose.material +package com.huanshankeji.compose.material2 import androidx.compose.runtime.Composable import com.huanshankeji.compose.ui.Modifier diff --git a/compose-multiplatform-material/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material/Icon.androidxCommon.kt b/compose-multiplatform-material2/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material2/Icon.androidxCommon.kt similarity index 88% rename from compose-multiplatform-material/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material/Icon.androidxCommon.kt rename to compose-multiplatform-material2/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material2/Icon.androidxCommon.kt index 96d73922..62561ab2 100644 --- a/compose-multiplatform-material/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material/Icon.androidxCommon.kt +++ b/compose-multiplatform-material2/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material2/Icon.androidxCommon.kt @@ -1,4 +1,4 @@ -package com.huanshankeji.compose.material +package com.huanshankeji.compose.material2 import androidx.compose.runtime.Composable import com.huanshankeji.compose.material.icons.Icon diff --git a/compose-multiplatform-material/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material/IconButton.androidxCommon.kt b/compose-multiplatform-material2/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material2/IconButton.androidxCommon.kt similarity index 93% rename from compose-multiplatform-material/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material/IconButton.androidxCommon.kt rename to compose-multiplatform-material2/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material2/IconButton.androidxCommon.kt index f3f951ca..ad32db0a 100644 --- a/compose-multiplatform-material/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material/IconButton.androidxCommon.kt +++ b/compose-multiplatform-material2/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material2/IconButton.androidxCommon.kt @@ -1,4 +1,4 @@ -package com.huanshankeji.compose.material +package com.huanshankeji.compose.material2 import androidx.compose.runtime.Composable import com.huanshankeji.compose.ui.Modifier diff --git a/compose-multiplatform-material/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material/Switch.androidxCommon.kt b/compose-multiplatform-material2/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material2/Switch.androidxCommon.kt similarity index 90% rename from compose-multiplatform-material/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material/Switch.androidxCommon.kt rename to compose-multiplatform-material2/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material2/Switch.androidxCommon.kt index 55098b13..4d7742cf 100644 --- a/compose-multiplatform-material/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material/Switch.androidxCommon.kt +++ b/compose-multiplatform-material2/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material2/Switch.androidxCommon.kt @@ -1,4 +1,4 @@ -package com.huanshankeji.compose.material +package com.huanshankeji.compose.material2 import androidx.compose.runtime.Composable import com.huanshankeji.compose.ui.Modifier diff --git a/compose-multiplatform-material/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material/Text.androidxCommon.kt b/compose-multiplatform-material2/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material2/Text.androidxCommon.kt similarity index 83% rename from compose-multiplatform-material/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material/Text.androidxCommon.kt rename to compose-multiplatform-material2/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material2/Text.androidxCommon.kt index 64f372f6..a5d0c347 100644 --- a/compose-multiplatform-material/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material/Text.androidxCommon.kt +++ b/compose-multiplatform-material2/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material2/Text.androidxCommon.kt @@ -1,4 +1,4 @@ -package com.huanshankeji.compose.material +package com.huanshankeji.compose.material2 import androidx.compose.runtime.Composable import com.huanshankeji.compose.ui.Modifier diff --git a/compose-multiplatform-material/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material/ext/Button.androidxCommon.kt b/compose-multiplatform-material2/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material2/ext/Button.androidxCommon.kt similarity index 90% rename from compose-multiplatform-material/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material/ext/Button.androidxCommon.kt rename to compose-multiplatform-material2/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material2/ext/Button.androidxCommon.kt index 2b5ebb67..78b5cbee 100644 --- a/compose-multiplatform-material/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material/ext/Button.androidxCommon.kt +++ b/compose-multiplatform-material2/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material2/ext/Button.androidxCommon.kt @@ -1,10 +1,10 @@ -package com.huanshankeji.compose.material.ext +package com.huanshankeji.compose.material2.ext import androidx.compose.foundation.layout.RowScope import androidx.compose.material.OutlinedButton import androidx.compose.material.TextButton import androidx.compose.runtime.Composable -import com.huanshankeji.compose.material.ext.ButtonType.* +import com.huanshankeji.compose.material2.ext.ButtonType.* import com.huanshankeji.compose.ui.Modifier @Suppress("NAME_SHADOWING") diff --git a/compose-multiplatform-material/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material/ext/Radio.androidxCommon.kt b/compose-multiplatform-material2/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material2/ext/Radio.androidxCommon.kt similarity index 96% rename from compose-multiplatform-material/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material/ext/Radio.androidxCommon.kt rename to compose-multiplatform-material2/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material2/ext/Radio.androidxCommon.kt index 4376c23a..514a5ff4 100644 --- a/compose-multiplatform-material/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material/ext/Radio.androidxCommon.kt +++ b/compose-multiplatform-material2/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material2/ext/Radio.androidxCommon.kt @@ -1,4 +1,4 @@ -package com.huanshankeji.compose.material.ext +package com.huanshankeji.compose.material2.ext import androidx.compose.foundation.layout.Row import androidx.compose.foundation.selection.selectable diff --git a/compose-multiplatform-material/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material/ext/Switch.androidxCommon.kt b/compose-multiplatform-material2/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material2/ext/Switch.androidxCommon.kt similarity index 82% rename from compose-multiplatform-material/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material/ext/Switch.androidxCommon.kt rename to compose-multiplatform-material2/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material2/ext/Switch.androidxCommon.kt index c248642d..857e5ef5 100644 --- a/compose-multiplatform-material/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material/ext/Switch.androidxCommon.kt +++ b/compose-multiplatform-material2/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material2/ext/Switch.androidxCommon.kt @@ -1,9 +1,9 @@ -package com.huanshankeji.compose.material.ext +package com.huanshankeji.compose.material2.ext import androidx.compose.material.Text import androidx.compose.runtime.Composable import com.huanshankeji.compose.foundation.layout.Row -import com.huanshankeji.compose.material.Switch +import com.huanshankeji.compose.material2.Switch import com.huanshankeji.compose.ui.Modifier @Composable diff --git a/compose-multiplatform-material/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material/ext/Text.androidxCommon.kt b/compose-multiplatform-material2/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material2/ext/Text.androidxCommon.kt similarity index 75% rename from compose-multiplatform-material/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material/ext/Text.androidxCommon.kt rename to compose-multiplatform-material2/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material2/ext/Text.androidxCommon.kt index d19e1b1e..e7c8016b 100644 --- a/compose-multiplatform-material/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material/ext/Text.androidxCommon.kt +++ b/compose-multiplatform-material2/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material2/ext/Text.androidxCommon.kt @@ -1,4 +1,4 @@ -package com.huanshankeji.compose.material.ext +package com.huanshankeji.compose.material2.ext import androidx.compose.material.Text import androidx.compose.runtime.Composable diff --git a/compose-multiplatform-material/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material/ext/TextField.androidxCommon.kt b/compose-multiplatform-material2/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material2/ext/TextField.androidxCommon.kt similarity index 96% rename from compose-multiplatform-material/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material/ext/TextField.androidxCommon.kt rename to compose-multiplatform-material2/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material2/ext/TextField.androidxCommon.kt index 6af5c925..f21bd824 100644 --- a/compose-multiplatform-material/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material/ext/TextField.androidxCommon.kt +++ b/compose-multiplatform-material2/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material2/ext/TextField.androidxCommon.kt @@ -1,12 +1,12 @@ -package com.huanshankeji.compose.material.ext +package com.huanshankeji.compose.material2.ext import androidx.compose.runtime.Composable import com.huanshankeji.compose.foundation.text.KeyboardActions import com.huanshankeji.compose.foundation.text.KeyboardOptions import com.huanshankeji.compose.foundation.text.toPlatformValue -import com.huanshankeji.compose.material.Icon -import com.huanshankeji.compose.material.Text import com.huanshankeji.compose.material.icons.Icon +import com.huanshankeji.compose.material2.Icon +import com.huanshankeji.compose.material2.Text import com.huanshankeji.compose.ui.Modifier @Composable diff --git a/compose-multiplatform-material/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material/ext/TopAppBarScaffold.androidxCommon.kt b/compose-multiplatform-material2/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material2/ext/TopAppBarScaffold.androidxCommon.kt similarity index 91% rename from compose-multiplatform-material/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material/ext/TopAppBarScaffold.androidxCommon.kt rename to compose-multiplatform-material2/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material2/ext/TopAppBarScaffold.androidxCommon.kt index a5862dae..4f47c58c 100644 --- a/compose-multiplatform-material/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material/ext/TopAppBarScaffold.androidxCommon.kt +++ b/compose-multiplatform-material2/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material2/ext/TopAppBarScaffold.androidxCommon.kt @@ -1,12 +1,12 @@ -package com.huanshankeji.compose.material.ext +package com.huanshankeji.compose.material2.ext import androidx.compose.foundation.layout.RowScope import androidx.compose.material.Scaffold import androidx.compose.material.TopAppBar import androidx.compose.runtime.Composable -import com.huanshankeji.compose.material.Icon -import com.huanshankeji.compose.material.IconButton import com.huanshankeji.compose.material.icons.Icon +import com.huanshankeji.compose.material2.Icon +import com.huanshankeji.compose.material2.IconButton import com.huanshankeji.compose.ui.Modifier actual class NavigationIconScope private constructor() { diff --git a/compose-multiplatform-material/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material/lazy/ext/LazyDsl.androidxCommon.kt b/compose-multiplatform-material2/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material2/lazy/ext/LazyDsl.androidxCommon.kt similarity index 97% rename from compose-multiplatform-material/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material/lazy/ext/LazyDsl.androidxCommon.kt rename to compose-multiplatform-material2/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material2/lazy/ext/LazyDsl.androidxCommon.kt index f281dd45..7a77b97d 100644 --- a/compose-multiplatform-material/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material/lazy/ext/LazyDsl.androidxCommon.kt +++ b/compose-multiplatform-material2/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material2/lazy/ext/LazyDsl.androidxCommon.kt @@ -1,4 +1,4 @@ -package com.huanshankeji.compose.material.lazy.ext +package com.huanshankeji.compose.material2.lazy.ext import androidx.compose.foundation.ExperimentalFoundationApi import androidx.compose.material.ExperimentalMaterialApi diff --git a/compose-multiplatform-material/src/commonMain/kotlin/com/huanshankeji/compose/material/Button.kt b/compose-multiplatform-material2/src/commonMain/kotlin/com/huanshankeji/compose/material2/Button.kt similarity index 93% rename from compose-multiplatform-material/src/commonMain/kotlin/com/huanshankeji/compose/material/Button.kt rename to compose-multiplatform-material2/src/commonMain/kotlin/com/huanshankeji/compose/material2/Button.kt index 30aa67ec..51b23c43 100644 --- a/compose-multiplatform-material/src/commonMain/kotlin/com/huanshankeji/compose/material/Button.kt +++ b/compose-multiplatform-material2/src/commonMain/kotlin/com/huanshankeji/compose/material2/Button.kt @@ -1,4 +1,4 @@ -package com.huanshankeji.compose.material +package com.huanshankeji.compose.material2 import androidx.compose.runtime.Composable import com.huanshankeji.compose.foundation.layout.RowScope diff --git a/compose-multiplatform-material/src/commonMain/kotlin/com/huanshankeji/compose/material/Card.kt b/compose-multiplatform-material2/src/commonMain/kotlin/com/huanshankeji/compose/material2/Card.kt similarity index 88% rename from compose-multiplatform-material/src/commonMain/kotlin/com/huanshankeji/compose/material/Card.kt rename to compose-multiplatform-material2/src/commonMain/kotlin/com/huanshankeji/compose/material2/Card.kt index 6ce99118..16fa783a 100644 --- a/compose-multiplatform-material/src/commonMain/kotlin/com/huanshankeji/compose/material/Card.kt +++ b/compose-multiplatform-material2/src/commonMain/kotlin/com/huanshankeji/compose/material2/Card.kt @@ -1,4 +1,4 @@ -package com.huanshankeji.compose.material +package com.huanshankeji.compose.material2 import androidx.compose.runtime.Composable import com.huanshankeji.compose.ui.Modifier diff --git a/compose-multiplatform-material/src/commonMain/kotlin/com/huanshankeji/compose/material/Checkbox.kt b/compose-multiplatform-material2/src/commonMain/kotlin/com/huanshankeji/compose/material2/Checkbox.kt similarity index 85% rename from compose-multiplatform-material/src/commonMain/kotlin/com/huanshankeji/compose/material/Checkbox.kt rename to compose-multiplatform-material2/src/commonMain/kotlin/com/huanshankeji/compose/material2/Checkbox.kt index 859275a9..394e81e9 100644 --- a/compose-multiplatform-material/src/commonMain/kotlin/com/huanshankeji/compose/material/Checkbox.kt +++ b/compose-multiplatform-material2/src/commonMain/kotlin/com/huanshankeji/compose/material2/Checkbox.kt @@ -1,4 +1,4 @@ -package com.huanshankeji.compose.material +package com.huanshankeji.compose.material2 import androidx.compose.runtime.Composable import com.huanshankeji.compose.ui.Modifier diff --git a/compose-multiplatform-material/src/commonMain/kotlin/com/huanshankeji/compose/material/Divider.kt b/compose-multiplatform-material2/src/commonMain/kotlin/com/huanshankeji/compose/material2/Divider.kt similarity index 84% rename from compose-multiplatform-material/src/commonMain/kotlin/com/huanshankeji/compose/material/Divider.kt rename to compose-multiplatform-material2/src/commonMain/kotlin/com/huanshankeji/compose/material2/Divider.kt index 6159c27f..63453cfd 100644 --- a/compose-multiplatform-material/src/commonMain/kotlin/com/huanshankeji/compose/material/Divider.kt +++ b/compose-multiplatform-material2/src/commonMain/kotlin/com/huanshankeji/compose/material2/Divider.kt @@ -1,4 +1,4 @@ -package com.huanshankeji.compose.material +package com.huanshankeji.compose.material2 import androidx.compose.runtime.Composable import com.huanshankeji.compose.ui.Modifier diff --git a/compose-multiplatform-material/src/commonMain/kotlin/com/huanshankeji/compose/material/Icon.kt b/compose-multiplatform-material2/src/commonMain/kotlin/com/huanshankeji/compose/material2/Icon.kt similarity index 85% rename from compose-multiplatform-material/src/commonMain/kotlin/com/huanshankeji/compose/material/Icon.kt rename to compose-multiplatform-material2/src/commonMain/kotlin/com/huanshankeji/compose/material2/Icon.kt index 6d2aff85..da4f8dc2 100644 --- a/compose-multiplatform-material/src/commonMain/kotlin/com/huanshankeji/compose/material/Icon.kt +++ b/compose-multiplatform-material2/src/commonMain/kotlin/com/huanshankeji/compose/material2/Icon.kt @@ -1,4 +1,4 @@ -package com.huanshankeji.compose.material +package com.huanshankeji.compose.material2 import androidx.compose.runtime.Composable import com.huanshankeji.compose.material.icons.Icon diff --git a/compose-multiplatform-material/src/commonMain/kotlin/com/huanshankeji/compose/material/IconButton.kt b/compose-multiplatform-material2/src/commonMain/kotlin/com/huanshankeji/compose/material2/IconButton.kt similarity index 90% rename from compose-multiplatform-material/src/commonMain/kotlin/com/huanshankeji/compose/material/IconButton.kt rename to compose-multiplatform-material2/src/commonMain/kotlin/com/huanshankeji/compose/material2/IconButton.kt index 5ef6c141..892ad67b 100644 --- a/compose-multiplatform-material/src/commonMain/kotlin/com/huanshankeji/compose/material/IconButton.kt +++ b/compose-multiplatform-material2/src/commonMain/kotlin/com/huanshankeji/compose/material2/IconButton.kt @@ -1,4 +1,4 @@ -package com.huanshankeji.compose.material +package com.huanshankeji.compose.material2 import androidx.compose.runtime.Composable import com.huanshankeji.compose.ui.Modifier diff --git a/compose-multiplatform-material/src/commonMain/kotlin/com/huanshankeji/compose/material/Switch.kt b/compose-multiplatform-material2/src/commonMain/kotlin/com/huanshankeji/compose/material2/Switch.kt similarity index 85% rename from compose-multiplatform-material/src/commonMain/kotlin/com/huanshankeji/compose/material/Switch.kt rename to compose-multiplatform-material2/src/commonMain/kotlin/com/huanshankeji/compose/material2/Switch.kt index 81075773..d7f20683 100644 --- a/compose-multiplatform-material/src/commonMain/kotlin/com/huanshankeji/compose/material/Switch.kt +++ b/compose-multiplatform-material2/src/commonMain/kotlin/com/huanshankeji/compose/material2/Switch.kt @@ -1,4 +1,4 @@ -package com.huanshankeji.compose.material +package com.huanshankeji.compose.material2 import androidx.compose.runtime.Composable import com.huanshankeji.compose.ui.Modifier diff --git a/compose-multiplatform-material/src/commonMain/kotlin/com/huanshankeji/compose/material/Text.kt b/compose-multiplatform-material2/src/commonMain/kotlin/com/huanshankeji/compose/material2/Text.kt similarity index 84% rename from compose-multiplatform-material/src/commonMain/kotlin/com/huanshankeji/compose/material/Text.kt rename to compose-multiplatform-material2/src/commonMain/kotlin/com/huanshankeji/compose/material2/Text.kt index 23534f87..7fc56d92 100644 --- a/compose-multiplatform-material/src/commonMain/kotlin/com/huanshankeji/compose/material/Text.kt +++ b/compose-multiplatform-material2/src/commonMain/kotlin/com/huanshankeji/compose/material2/Text.kt @@ -1,7 +1,7 @@ -package com.huanshankeji.compose.material +package com.huanshankeji.compose.material2 import androidx.compose.runtime.Composable -import com.huanshankeji.compose.material.ext.InlineText +import com.huanshankeji.compose.material2.ext.InlineText import com.huanshankeji.compose.ui.Modifier /** diff --git a/compose-multiplatform-material/src/commonMain/kotlin/com/huanshankeji/compose/material/ext/Button.kt b/compose-multiplatform-material2/src/commonMain/kotlin/com/huanshankeji/compose/material2/ext/Button.kt similarity index 89% rename from compose-multiplatform-material/src/commonMain/kotlin/com/huanshankeji/compose/material/ext/Button.kt rename to compose-multiplatform-material2/src/commonMain/kotlin/com/huanshankeji/compose/material2/ext/Button.kt index cd088f72..5f738e6e 100644 --- a/compose-multiplatform-material/src/commonMain/kotlin/com/huanshankeji/compose/material/ext/Button.kt +++ b/compose-multiplatform-material2/src/commonMain/kotlin/com/huanshankeji/compose/material2/ext/Button.kt @@ -1,4 +1,4 @@ -package com.huanshankeji.compose.material.ext +package com.huanshankeji.compose.material2.ext import androidx.compose.runtime.Composable import com.huanshankeji.compose.ui.Modifier diff --git a/compose-multiplatform-material/src/commonMain/kotlin/com/huanshankeji/compose/material/ext/IconButton.kt b/compose-multiplatform-material2/src/commonMain/kotlin/com/huanshankeji/compose/material2/ext/IconButton.kt similarity index 58% rename from compose-multiplatform-material/src/commonMain/kotlin/com/huanshankeji/compose/material/ext/IconButton.kt rename to compose-multiplatform-material2/src/commonMain/kotlin/com/huanshankeji/compose/material2/ext/IconButton.kt index 3cb78cb3..551af428 100644 --- a/compose-multiplatform-material/src/commonMain/kotlin/com/huanshankeji/compose/material/ext/IconButton.kt +++ b/compose-multiplatform-material2/src/commonMain/kotlin/com/huanshankeji/compose/material2/ext/IconButton.kt @@ -1,8 +1,8 @@ -package com.huanshankeji.compose.material.ext +package com.huanshankeji.compose.material2.ext import androidx.compose.runtime.Composable -import com.huanshankeji.compose.material.Icon import com.huanshankeji.compose.material.icons.Icon +import com.huanshankeji.compose.material2.Icon import com.huanshankeji.compose.ui.Modifier @Composable @@ -12,4 +12,4 @@ fun IconButton( icon: Icon, contentDescription: String? ) = - com.huanshankeji.compose.material.IconButton(onClick, modifier) { Icon(icon, contentDescription) } + com.huanshankeji.compose.material2.IconButton(onClick, modifier) { Icon(icon, contentDescription) } diff --git a/compose-multiplatform-material/src/commonMain/kotlin/com/huanshankeji/compose/material/ext/Radio.kt b/compose-multiplatform-material2/src/commonMain/kotlin/com/huanshankeji/compose/material2/ext/Radio.kt similarity index 89% rename from compose-multiplatform-material/src/commonMain/kotlin/com/huanshankeji/compose/material/ext/Radio.kt rename to compose-multiplatform-material2/src/commonMain/kotlin/com/huanshankeji/compose/material2/ext/Radio.kt index 4aea9033..2f2b1d47 100644 --- a/compose-multiplatform-material/src/commonMain/kotlin/com/huanshankeji/compose/material/ext/Radio.kt +++ b/compose-multiplatform-material2/src/commonMain/kotlin/com/huanshankeji/compose/material2/ext/Radio.kt @@ -1,4 +1,4 @@ -package com.huanshankeji.compose.material.ext +package com.huanshankeji.compose.material2.ext import androidx.compose.runtime.Composable import com.huanshankeji.compose.ui.Modifier diff --git a/compose-multiplatform-material/src/commonMain/kotlin/com/huanshankeji/compose/material/ext/Switch.kt b/compose-multiplatform-material2/src/commonMain/kotlin/com/huanshankeji/compose/material2/ext/Switch.kt similarity index 85% rename from compose-multiplatform-material/src/commonMain/kotlin/com/huanshankeji/compose/material/ext/Switch.kt rename to compose-multiplatform-material2/src/commonMain/kotlin/com/huanshankeji/compose/material2/ext/Switch.kt index 82326fc9..2e2adc01 100644 --- a/compose-multiplatform-material/src/commonMain/kotlin/com/huanshankeji/compose/material/ext/Switch.kt +++ b/compose-multiplatform-material2/src/commonMain/kotlin/com/huanshankeji/compose/material2/ext/Switch.kt @@ -1,4 +1,4 @@ -package com.huanshankeji.compose.material.ext +package com.huanshankeji.compose.material2.ext import androidx.compose.runtime.Composable import com.huanshankeji.compose.ui.Modifier diff --git a/compose-multiplatform-material/src/commonMain/kotlin/com/huanshankeji/compose/material/ext/Text.kt b/compose-multiplatform-material2/src/commonMain/kotlin/com/huanshankeji/compose/material2/ext/Text.kt similarity index 82% rename from compose-multiplatform-material/src/commonMain/kotlin/com/huanshankeji/compose/material/ext/Text.kt rename to compose-multiplatform-material2/src/commonMain/kotlin/com/huanshankeji/compose/material2/ext/Text.kt index 097dc7de..97589382 100644 --- a/compose-multiplatform-material/src/commonMain/kotlin/com/huanshankeji/compose/material/ext/Text.kt +++ b/compose-multiplatform-material2/src/commonMain/kotlin/com/huanshankeji/compose/material2/ext/Text.kt @@ -1,7 +1,7 @@ -package com.huanshankeji.compose.material.ext +package com.huanshankeji.compose.material2.ext import androidx.compose.runtime.Composable -import com.huanshankeji.compose.material.Text +import com.huanshankeji.compose.material2.Text import com.huanshankeji.compose.ui.Modifier /** diff --git a/compose-multiplatform-material/src/commonMain/kotlin/com/huanshankeji/compose/material/ext/TextField.kt b/compose-multiplatform-material2/src/commonMain/kotlin/com/huanshankeji/compose/material2/ext/TextField.kt similarity index 98% rename from compose-multiplatform-material/src/commonMain/kotlin/com/huanshankeji/compose/material/ext/TextField.kt rename to compose-multiplatform-material2/src/commonMain/kotlin/com/huanshankeji/compose/material2/ext/TextField.kt index 17d19b69..0155f69f 100644 --- a/compose-multiplatform-material/src/commonMain/kotlin/com/huanshankeji/compose/material/ext/TextField.kt +++ b/compose-multiplatform-material2/src/commonMain/kotlin/com/huanshankeji/compose/material2/ext/TextField.kt @@ -1,4 +1,4 @@ -package com.huanshankeji.compose.material.ext +package com.huanshankeji.compose.material2.ext import androidx.compose.runtime.Composable import com.huanshankeji.compose.foundation.text.KeyboardActions diff --git a/compose-multiplatform-material/src/commonMain/kotlin/com/huanshankeji/compose/material/ext/TopAppBarScaffold.kt b/compose-multiplatform-material2/src/commonMain/kotlin/com/huanshankeji/compose/material2/ext/TopAppBarScaffold.kt similarity index 95% rename from compose-multiplatform-material/src/commonMain/kotlin/com/huanshankeji/compose/material/ext/TopAppBarScaffold.kt rename to compose-multiplatform-material2/src/commonMain/kotlin/com/huanshankeji/compose/material2/ext/TopAppBarScaffold.kt index 12edd3d3..13f9c465 100644 --- a/compose-multiplatform-material/src/commonMain/kotlin/com/huanshankeji/compose/material/ext/TopAppBarScaffold.kt +++ b/compose-multiplatform-material2/src/commonMain/kotlin/com/huanshankeji/compose/material2/ext/TopAppBarScaffold.kt @@ -1,4 +1,4 @@ -package com.huanshankeji.compose.material.ext +package com.huanshankeji.compose.material2.ext import androidx.compose.runtime.Composable import com.huanshankeji.compose.material.icons.Icon diff --git a/compose-multiplatform-material/src/commonMain/kotlin/com/huanshankeji/compose/material/lazy/ext/LazyDsl.kt b/compose-multiplatform-material2/src/commonMain/kotlin/com/huanshankeji/compose/material2/lazy/ext/LazyDsl.kt similarity index 94% rename from compose-multiplatform-material/src/commonMain/kotlin/com/huanshankeji/compose/material/lazy/ext/LazyDsl.kt rename to compose-multiplatform-material2/src/commonMain/kotlin/com/huanshankeji/compose/material2/lazy/ext/LazyDsl.kt index fdca7ca1..e16d310a 100644 --- a/compose-multiplatform-material/src/commonMain/kotlin/com/huanshankeji/compose/material/lazy/ext/LazyDsl.kt +++ b/compose-multiplatform-material2/src/commonMain/kotlin/com/huanshankeji/compose/material2/lazy/ext/LazyDsl.kt @@ -1,7 +1,7 @@ -package com.huanshankeji.compose.material.lazy.ext +package com.huanshankeji.compose.material2.lazy.ext import androidx.compose.runtime.Composable -import com.huanshankeji.compose.material.ext.InlineText +import com.huanshankeji.compose.material2.ext.InlineText import com.huanshankeji.compose.ui.Modifier expect class ListScope { diff --git a/compose-multiplatform-material/src/jsMain/kotlin/com/huanshankeji/compose/material/Button.js.kt b/compose-multiplatform-material2/src/jsMain/kotlin/com/huanshankeji/compose/material2/Button.js.kt similarity index 90% rename from compose-multiplatform-material/src/jsMain/kotlin/com/huanshankeji/compose/material/Button.js.kt rename to compose-multiplatform-material2/src/jsMain/kotlin/com/huanshankeji/compose/material2/Button.js.kt index 92b78eb1..179e261f 100644 --- a/compose-multiplatform-material/src/jsMain/kotlin/com/huanshankeji/compose/material/Button.js.kt +++ b/compose-multiplatform-material2/src/jsMain/kotlin/com/huanshankeji/compose/material2/Button.js.kt @@ -1,10 +1,10 @@ -package com.huanshankeji.compose.material +package com.huanshankeji.compose.material2 import androidx.compose.runtime.Composable import com.huanshankeji.compose.foundation.layout.Row import com.huanshankeji.compose.foundation.layout.RowScope -import com.huanshankeji.compose.material.ext.ButtonType -import com.huanshankeji.compose.material.ext.toMDCButtonType +import com.huanshankeji.compose.material2.ext.ButtonType +import com.huanshankeji.compose.material2.ext.toMDCButtonType import com.huanshankeji.compose.ui.Modifier import com.varabyte.kobweb.compose.ui.toAttrs import dev.petuska.kmdc.button.MDCButton diff --git a/compose-multiplatform-material/src/jsMain/kotlin/com/huanshankeji/compose/material/Card.js.kt b/compose-multiplatform-material2/src/jsMain/kotlin/com/huanshankeji/compose/material2/Card.js.kt similarity index 91% rename from compose-multiplatform-material/src/jsMain/kotlin/com/huanshankeji/compose/material/Card.js.kt rename to compose-multiplatform-material2/src/jsMain/kotlin/com/huanshankeji/compose/material2/Card.js.kt index f5b369cd..60e0a6c5 100644 --- a/compose-multiplatform-material/src/jsMain/kotlin/com/huanshankeji/compose/material/Card.js.kt +++ b/compose-multiplatform-material2/src/jsMain/kotlin/com/huanshankeji/compose/material2/Card.js.kt @@ -1,4 +1,4 @@ -package com.huanshankeji.compose.material +package com.huanshankeji.compose.material2 import androidx.compose.runtime.Composable import com.huanshankeji.compose.ui.Modifier diff --git a/compose-multiplatform-material/src/jsMain/kotlin/com/huanshankeji/compose/material/Checkbox.js.kt b/compose-multiplatform-material2/src/jsMain/kotlin/com/huanshankeji/compose/material2/Checkbox.js.kt similarity index 92% rename from compose-multiplatform-material/src/jsMain/kotlin/com/huanshankeji/compose/material/Checkbox.js.kt rename to compose-multiplatform-material2/src/jsMain/kotlin/com/huanshankeji/compose/material2/Checkbox.js.kt index ec5f0a56..5c4ef37f 100644 --- a/compose-multiplatform-material/src/jsMain/kotlin/com/huanshankeji/compose/material/Checkbox.js.kt +++ b/compose-multiplatform-material2/src/jsMain/kotlin/com/huanshankeji/compose/material2/Checkbox.js.kt @@ -1,4 +1,4 @@ -package com.huanshankeji.compose.material +package com.huanshankeji.compose.material2 import androidx.compose.runtime.Composable import com.huanshankeji.compose.ui.Modifier diff --git a/compose-multiplatform-material/src/jsMain/kotlin/com/huanshankeji/compose/material/Divider.js.kt b/compose-multiplatform-material2/src/jsMain/kotlin/com/huanshankeji/compose/material2/Divider.js.kt similarity index 93% rename from compose-multiplatform-material/src/jsMain/kotlin/com/huanshankeji/compose/material/Divider.js.kt rename to compose-multiplatform-material2/src/jsMain/kotlin/com/huanshankeji/compose/material2/Divider.js.kt index e9394053..c2ff8287 100644 --- a/compose-multiplatform-material/src/jsMain/kotlin/com/huanshankeji/compose/material/Divider.js.kt +++ b/compose-multiplatform-material2/src/jsMain/kotlin/com/huanshankeji/compose/material2/Divider.js.kt @@ -1,4 +1,4 @@ -package com.huanshankeji.compose.material +package com.huanshankeji.compose.material2 import androidx.compose.runtime.Composable import com.huanshankeji.compose.ui.Modifier diff --git a/compose-multiplatform-material/src/jsMain/kotlin/com/huanshankeji/compose/material/Icon.js.kt b/compose-multiplatform-material2/src/jsMain/kotlin/com/huanshankeji/compose/material2/Icon.js.kt similarity index 86% rename from compose-multiplatform-material/src/jsMain/kotlin/com/huanshankeji/compose/material/Icon.js.kt rename to compose-multiplatform-material2/src/jsMain/kotlin/com/huanshankeji/compose/material2/Icon.js.kt index b4dfc4ed..eda10d78 100644 --- a/compose-multiplatform-material/src/jsMain/kotlin/com/huanshankeji/compose/material/Icon.js.kt +++ b/compose-multiplatform-material2/src/jsMain/kotlin/com/huanshankeji/compose/material2/Icon.js.kt @@ -1,9 +1,9 @@ -package com.huanshankeji.compose.material +package com.huanshankeji.compose.material2 import androidx.compose.runtime.Composable import com.huanshankeji.compose.contentDescription import com.huanshankeji.compose.material.icons.Icon -import com.huanshankeji.compose.material.icons.toMDCIcon +import com.huanshankeji.compose.material2.icons.toMDCIcon import com.huanshankeji.compose.ui.Modifier import com.varabyte.kobweb.compose.ui.toAttrs import dev.petuska.kmdcx.icons.MDCIconSpan diff --git a/compose-multiplatform-material/src/jsMain/kotlin/com/huanshankeji/compose/material/IconButton.js.kt b/compose-multiplatform-material2/src/jsMain/kotlin/com/huanshankeji/compose/material2/IconButton.js.kt similarity index 93% rename from compose-multiplatform-material/src/jsMain/kotlin/com/huanshankeji/compose/material/IconButton.js.kt rename to compose-multiplatform-material2/src/jsMain/kotlin/com/huanshankeji/compose/material2/IconButton.js.kt index e38d353a..462d6aee 100644 --- a/compose-multiplatform-material/src/jsMain/kotlin/com/huanshankeji/compose/material/IconButton.js.kt +++ b/compose-multiplatform-material2/src/jsMain/kotlin/com/huanshankeji/compose/material2/IconButton.js.kt @@ -1,4 +1,4 @@ -package com.huanshankeji.compose.material +package com.huanshankeji.compose.material2 import androidx.compose.runtime.Composable import com.huanshankeji.compose.ui.Modifier diff --git a/compose-multiplatform-material/src/jsMain/kotlin/com/huanshankeji/compose/material/Switch.js.kt b/compose-multiplatform-material2/src/jsMain/kotlin/com/huanshankeji/compose/material2/Switch.js.kt similarity index 95% rename from compose-multiplatform-material/src/jsMain/kotlin/com/huanshankeji/compose/material/Switch.js.kt rename to compose-multiplatform-material2/src/jsMain/kotlin/com/huanshankeji/compose/material2/Switch.js.kt index 5e737ef5..af56719f 100644 --- a/compose-multiplatform-material/src/jsMain/kotlin/com/huanshankeji/compose/material/Switch.js.kt +++ b/compose-multiplatform-material2/src/jsMain/kotlin/com/huanshankeji/compose/material2/Switch.js.kt @@ -1,4 +1,4 @@ -package com.huanshankeji.compose.material +package com.huanshankeji.compose.material2 import androidx.compose.runtime.Composable import com.huanshankeji.compose.ui.Modifier diff --git a/compose-multiplatform-material/src/jsMain/kotlin/com/huanshankeji/compose/material/Text.js.kt b/compose-multiplatform-material2/src/jsMain/kotlin/com/huanshankeji/compose/material2/Text.js.kt similarity index 84% rename from compose-multiplatform-material/src/jsMain/kotlin/com/huanshankeji/compose/material/Text.js.kt rename to compose-multiplatform-material2/src/jsMain/kotlin/com/huanshankeji/compose/material2/Text.js.kt index 334a347b..a3733ad5 100644 --- a/compose-multiplatform-material/src/jsMain/kotlin/com/huanshankeji/compose/material/Text.js.kt +++ b/compose-multiplatform-material2/src/jsMain/kotlin/com/huanshankeji/compose/material2/Text.js.kt @@ -1,4 +1,4 @@ -package com.huanshankeji.compose.material +package com.huanshankeji.compose.material2 import androidx.compose.runtime.Composable import com.huanshankeji.compose.foundation.text.BasicText diff --git a/compose-multiplatform-material/src/jsMain/kotlin/com/huanshankeji/compose/material/ext/Button.js.kt b/compose-multiplatform-material2/src/jsMain/kotlin/com/huanshankeji/compose/material2/ext/Button.js.kt similarity index 84% rename from compose-multiplatform-material/src/jsMain/kotlin/com/huanshankeji/compose/material/ext/Button.js.kt rename to compose-multiplatform-material2/src/jsMain/kotlin/com/huanshankeji/compose/material2/ext/Button.js.kt index b7383876..baca4925 100644 --- a/compose-multiplatform-material/src/jsMain/kotlin/com/huanshankeji/compose/material/ext/Button.js.kt +++ b/compose-multiplatform-material2/src/jsMain/kotlin/com/huanshankeji/compose/material2/ext/Button.js.kt @@ -1,8 +1,8 @@ -package com.huanshankeji.compose.material.ext +package com.huanshankeji.compose.material2.ext import androidx.compose.runtime.Composable -import com.huanshankeji.compose.material.CommonButton -import com.huanshankeji.compose.material.ext.ButtonType.* +import com.huanshankeji.compose.material2.CommonButton +import com.huanshankeji.compose.material2.ext.ButtonType.* import com.huanshankeji.compose.ui.Modifier import dev.petuska.kmdc.button.Label import dev.petuska.kmdc.button.MDCButtonScope diff --git a/compose-multiplatform-material/src/jsMain/kotlin/com/huanshankeji/compose/material/ext/Radio.js.kt b/compose-multiplatform-material2/src/jsMain/kotlin/com/huanshankeji/compose/material2/ext/Radio.js.kt similarity index 94% rename from compose-multiplatform-material/src/jsMain/kotlin/com/huanshankeji/compose/material/ext/Radio.js.kt rename to compose-multiplatform-material2/src/jsMain/kotlin/com/huanshankeji/compose/material2/ext/Radio.js.kt index a873cfd4..ff32f390 100644 --- a/compose-multiplatform-material/src/jsMain/kotlin/com/huanshankeji/compose/material/ext/Radio.js.kt +++ b/compose-multiplatform-material2/src/jsMain/kotlin/com/huanshankeji/compose/material2/ext/Radio.js.kt @@ -1,4 +1,4 @@ -package com.huanshankeji.compose.material.ext +package com.huanshankeji.compose.material2.ext import androidx.compose.runtime.Composable import com.huanshankeji.compose.ui.Modifier diff --git a/compose-multiplatform-material/src/jsMain/kotlin/com/huanshankeji/compose/material/ext/Switch.js.kt b/compose-multiplatform-material2/src/jsMain/kotlin/com/huanshankeji/compose/material2/ext/Switch.js.kt similarity index 76% rename from compose-multiplatform-material/src/jsMain/kotlin/com/huanshankeji/compose/material/ext/Switch.js.kt rename to compose-multiplatform-material2/src/jsMain/kotlin/com/huanshankeji/compose/material2/ext/Switch.js.kt index 75c42548..953de130 100644 --- a/compose-multiplatform-material/src/jsMain/kotlin/com/huanshankeji/compose/material/ext/Switch.js.kt +++ b/compose-multiplatform-material2/src/jsMain/kotlin/com/huanshankeji/compose/material2/ext/Switch.js.kt @@ -1,7 +1,7 @@ -package com.huanshankeji.compose.material.ext +package com.huanshankeji.compose.material2.ext import androidx.compose.runtime.Composable -import com.huanshankeji.compose.material.CommonSwitch +import com.huanshankeji.compose.material2.CommonSwitch import com.huanshankeji.compose.ui.Modifier @Composable diff --git a/compose-multiplatform-material/src/jsMain/kotlin/com/huanshankeji/compose/material/ext/Text.js.kt b/compose-multiplatform-material2/src/jsMain/kotlin/com/huanshankeji/compose/material2/ext/Text.js.kt similarity index 76% rename from compose-multiplatform-material/src/jsMain/kotlin/com/huanshankeji/compose/material/ext/Text.js.kt rename to compose-multiplatform-material2/src/jsMain/kotlin/com/huanshankeji/compose/material2/ext/Text.js.kt index a9cc6bb2..85e471c1 100644 --- a/compose-multiplatform-material/src/jsMain/kotlin/com/huanshankeji/compose/material/ext/Text.js.kt +++ b/compose-multiplatform-material2/src/jsMain/kotlin/com/huanshankeji/compose/material2/ext/Text.js.kt @@ -1,4 +1,4 @@ -package com.huanshankeji.compose.material.ext +package com.huanshankeji.compose.material2.ext import androidx.compose.runtime.Composable import org.jetbrains.compose.web.dom.Text diff --git a/compose-multiplatform-material/src/jsMain/kotlin/com/huanshankeji/compose/material/ext/TextField.js.kt b/compose-multiplatform-material2/src/jsMain/kotlin/com/huanshankeji/compose/material2/ext/TextField.js.kt similarity index 99% rename from compose-multiplatform-material/src/jsMain/kotlin/com/huanshankeji/compose/material/ext/TextField.js.kt rename to compose-multiplatform-material2/src/jsMain/kotlin/com/huanshankeji/compose/material2/ext/TextField.js.kt index da66fdd4..42cde6a1 100644 --- a/compose-multiplatform-material/src/jsMain/kotlin/com/huanshankeji/compose/material/ext/TextField.js.kt +++ b/compose-multiplatform-material2/src/jsMain/kotlin/com/huanshankeji/compose/material2/ext/TextField.js.kt @@ -1,4 +1,4 @@ -package com.huanshankeji.compose.material.ext +package com.huanshankeji.compose.material2.ext import androidx.compose.runtime.Composable import com.huanshankeji.compose.foundation.text.KeyboardActions diff --git a/compose-multiplatform-material/src/jsMain/kotlin/com/huanshankeji/compose/material/ext/TopAppBarScaffold.js.kt b/compose-multiplatform-material2/src/jsMain/kotlin/com/huanshankeji/compose/material2/ext/TopAppBarScaffold.js.kt similarity index 98% rename from compose-multiplatform-material/src/jsMain/kotlin/com/huanshankeji/compose/material/ext/TopAppBarScaffold.js.kt rename to compose-multiplatform-material2/src/jsMain/kotlin/com/huanshankeji/compose/material2/ext/TopAppBarScaffold.js.kt index 93479b63..94f6faae 100644 --- a/compose-multiplatform-material/src/jsMain/kotlin/com/huanshankeji/compose/material/ext/TopAppBarScaffold.js.kt +++ b/compose-multiplatform-material2/src/jsMain/kotlin/com/huanshankeji/compose/material2/ext/TopAppBarScaffold.js.kt @@ -1,4 +1,4 @@ -package com.huanshankeji.compose.material.ext +package com.huanshankeji.compose.material2.ext import androidx.compose.runtime.Composable import com.huanshankeji.compose.contentDescription diff --git a/compose-multiplatform-material/src/jsMain/kotlin/com/huanshankeji/compose/material/icons/IconsMdc.kt b/compose-multiplatform-material2/src/jsMain/kotlin/com/huanshankeji/compose/material2/icons/IconsMdc.kt similarity index 60% rename from compose-multiplatform-material/src/jsMain/kotlin/com/huanshankeji/compose/material/icons/IconsMdc.kt rename to compose-multiplatform-material2/src/jsMain/kotlin/com/huanshankeji/compose/material2/icons/IconsMdc.kt index 6d11198c..bd2a5b71 100644 --- a/compose-multiplatform-material/src/jsMain/kotlin/com/huanshankeji/compose/material/icons/IconsMdc.kt +++ b/compose-multiplatform-material2/src/jsMain/kotlin/com/huanshankeji/compose/material2/icons/IconsMdc.kt @@ -1,5 +1,6 @@ -package com.huanshankeji.compose.material.icons +package com.huanshankeji.compose.material2.icons +import com.huanshankeji.compose.material.icons.Icon import dev.petuska.kmdcx.icons.MDCIcon val mdcIconMap = MDCIcon.entries.associateBy { it.type } diff --git a/compose-multiplatform-material/src/jsMain/kotlin/com/huanshankeji/compose/material/lazy/ext/LazyDsl.js.kt b/compose-multiplatform-material2/src/jsMain/kotlin/com/huanshankeji/compose/material2/lazy/ext/LazyDsl.js.kt similarity index 98% rename from compose-multiplatform-material/src/jsMain/kotlin/com/huanshankeji/compose/material/lazy/ext/LazyDsl.js.kt rename to compose-multiplatform-material2/src/jsMain/kotlin/com/huanshankeji/compose/material2/lazy/ext/LazyDsl.js.kt index 4bd1bdad..522c9da3 100644 --- a/compose-multiplatform-material/src/jsMain/kotlin/com/huanshankeji/compose/material/lazy/ext/LazyDsl.js.kt +++ b/compose-multiplatform-material2/src/jsMain/kotlin/com/huanshankeji/compose/material2/lazy/ext/LazyDsl.js.kt @@ -1,4 +1,4 @@ -package com.huanshankeji.compose.material.lazy.ext +package com.huanshankeji.compose.material2.lazy.ext import androidx.compose.runtime.Composable import com.huanshankeji.compose.foundation.verticalScrollPlatformModifier diff --git a/demo/build.gradle.kts b/demo/build.gradle.kts index 9cde3d94..3b2d64a9 100644 --- a/demo/build.gradle.kts +++ b/demo/build.gradle.kts @@ -46,7 +46,7 @@ kotlin { commonMain { dependencies { implementation(compose.runtime) - implementation(project(":compose-multiplatform-material")) + implementation(project(":compose-multiplatform-material2")) implementation(project(":compose-multiplatform-material3")) } } diff --git a/demo/src/commonMain/kotlin/com/huanshankeji/compose/material/demo/Material2.kt b/demo/src/commonMain/kotlin/com/huanshankeji/compose/material/demo/Material2.kt index 858ef626..55b5b641 100644 --- a/demo/src/commonMain/kotlin/com/huanshankeji/compose/material/demo/Material2.kt +++ b/demo/src/commonMain/kotlin/com/huanshankeji/compose/material/demo/Material2.kt @@ -14,19 +14,19 @@ import com.huanshankeji.compose.foundation.text.input.KeyboardType import com.huanshankeji.compose.layout.height import com.huanshankeji.compose.layout.padding import com.huanshankeji.compose.layout.width -import com.huanshankeji.compose.material.* -import com.huanshankeji.compose.material.ext.* import com.huanshankeji.compose.material.icons.Icons import com.huanshankeji.compose.material.icons.filled.Add import com.huanshankeji.compose.material.icons.filled.Menu import com.huanshankeji.compose.material.icons.filled.Search -import com.huanshankeji.compose.material.lazy.ext.List -import com.huanshankeji.compose.material.lazy.ext.ListItemComponents -import com.huanshankeji.compose.material.lazy.ext.conventionalItem -import com.huanshankeji.compose.material.lazy.ext.conventionalItems +import com.huanshankeji.compose.material2.* +import com.huanshankeji.compose.material2.ext.* +import com.huanshankeji.compose.material2.lazy.ext.List +import com.huanshankeji.compose.material2.lazy.ext.ListItemComponents +import com.huanshankeji.compose.material2.lazy.ext.conventionalItem +import com.huanshankeji.compose.material2.lazy.ext.conventionalItems import com.huanshankeji.compose.ui.Modifier import com.huanshankeji.compose.ui.graphics.Color -import com.huanshankeji.compose.material.ext.Button as ExtButton +import com.huanshankeji.compose.material2.ext.Button as ExtButton @Composable fun Material2() { diff --git a/settings.gradle.kts b/settings.gradle.kts index 1e003326..128fa6fe 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -4,7 +4,7 @@ include("compose-multiplatform-common") // TODO consider splitting into several include("compose-multiplatform-common:legacy") project(":compose-multiplatform-common:legacy").name = "compose-multiplatform-common-legacy" include("compose-multiplatform-material-icons-core") -include("compose-multiplatform-material") +include("compose-multiplatform-material2") include("compose-multiplatform-material3") include("demo") From aa69d22bcd1a29ccf76905a81f506102a3e54faa Mon Sep 17 00:00:00 2001 From: Shreck Ye Date: Wed, 8 May 2024 22:34:51 +0800 Subject: [PATCH 68/75] Update some texts in the demo --- .../kotlin/com/huanshankeji/compose/material/demo/Common.kt | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/demo/src/commonMain/kotlin/com/huanshankeji/compose/material/demo/Common.kt b/demo/src/commonMain/kotlin/com/huanshankeji/compose/material/demo/Common.kt index 9081523d..8558535f 100644 --- a/demo/src/commonMain/kotlin/com/huanshankeji/compose/material/demo/Common.kt +++ b/demo/src/commonMain/kotlin/com/huanshankeji/compose/material/demo/Common.kt @@ -55,12 +55,14 @@ fun Common() { } var count by remember { mutableStateOf(0) } - BasicText("Click to add items to `LazyColumn` and `LazyRow`", Modifier.onClick { count++ }) + BasicText("Click to add items", Modifier.onClick { count++ }) val lazyListContent: LazyListScope.() -> Unit = { item { BasicText("Item") } items(count) { index -> BasicText("Item $index") } } + BasicText("`LazyColumn`") LazyColumn(Modifier.height(listSize), content = lazyListContent) + BasicText("`LazyRow`") LazyRow(Modifier.width(listSize), content = lazyListContent) @Composable @@ -68,9 +70,11 @@ fun Common() { BasicText("Item") repeat(count) { index -> BasicText("Item $index") } } + BasicText("`Column` with scroll") Column(Modifier.height(listSize).verticalScroll(rememberScrollState())) { ColumnOrRowContent() } + BasicText("`Row` with scroll") Row(Modifier.width(listSize).horizontalScroll(rememberScrollState())) { ColumnOrRowContent() } From 83962de371d91a7ab94b6ead695a9f11c29eee7c Mon Sep 17 00:00:00 2001 From: Shreck Ye Date: Thu, 9 May 2024 09:18:50 +0800 Subject: [PATCH 69/75] Add the card composables and test them in the demo, extract some common functions, and revamp `ColumnScope` and `RowScope` Scrolling is enabled in the demo because there are too many components now to fit in. The corresponding commit: https://github.com/huanshankeji/compose-html-material/commit/49057370fb8d9fd43b181bae4455ee277fc97b75 --- .../layout/Column.androidxCommon.kt | 11 +++--- .../foundation/layout/Row.androidxCommon.kt | 12 +++---- .../com/huanshankeji/compose/Content.kt | 7 ++++ .../compose/foundation/layout/Column.kt | 12 +++++++ .../compose/foundation/layout/Row.kt | 10 ++++++ .../compose/foundation/layout/Column.js.kt | 13 ++++--- .../compose/foundation/layout/Row.js.kt | 12 +++---- .../compose/material3/Card.androidxCommon.kt | 18 ++++++++++ .../material3/ext/Card.androidxCommon.kt | 16 +++++++++ .../huanshankeji/compose/material3/Card.kt | 36 +++++++++++++++++++ .../compose/material3/ext/Card.kt | 32 +++++++++++++++++ .../huanshankeji/compose/material3/Card.js.kt | 34 ++++++++++++++++++ .../compose/material3/ext/Card.js.kt | 24 +++++++++++++ .../huanshankeji/compose/material/demo/App.kt | 23 +++++++----- .../compose/material/demo/Common.kt | 4 +-- .../compose/material/demo/Material2.kt | 8 ++--- .../compose/material/demo/Material3.kt | 13 +++++-- 17 files changed, 246 insertions(+), 39 deletions(-) create mode 100644 compose-multiplatform-common/src/commonMain/kotlin/com/huanshankeji/compose/Content.kt create mode 100644 compose-multiplatform-material3/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material3/Card.androidxCommon.kt create mode 100644 compose-multiplatform-material3/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material3/ext/Card.androidxCommon.kt create mode 100644 compose-multiplatform-material3/src/commonMain/kotlin/com/huanshankeji/compose/material3/Card.kt create mode 100644 compose-multiplatform-material3/src/commonMain/kotlin/com/huanshankeji/compose/material3/ext/Card.kt create mode 100644 compose-multiplatform-material3/src/jsMain/kotlin/com/huanshankeji/compose/material3/Card.js.kt create mode 100644 compose-multiplatform-material3/src/jsMain/kotlin/com/huanshankeji/compose/material3/ext/Card.js.kt diff --git a/compose-multiplatform-common/src/androidxCommonMain/kotlin/com/huanshankeji/compose/foundation/layout/Column.androidxCommon.kt b/compose-multiplatform-common/src/androidxCommonMain/kotlin/com/huanshankeji/compose/foundation/layout/Column.androidxCommon.kt index 278109e4..fd186ea2 100644 --- a/compose-multiplatform-common/src/androidxCommonMain/kotlin/com/huanshankeji/compose/foundation/layout/Column.androidxCommon.kt +++ b/compose-multiplatform-common/src/androidxCommonMain/kotlin/com/huanshankeji/compose/foundation/layout/Column.androidxCommon.kt @@ -6,7 +6,6 @@ import androidx.compose.runtime.Stable import com.huanshankeji.compose.ui.Alignment import com.huanshankeji.compose.ui.Modifier import kotlin.jvm.JvmInline -import androidx.compose.foundation.layout.ColumnScope as PlatformColumnScope @Composable actual fun Column( @@ -19,14 +18,18 @@ actual fun Column( modifier.platformModifier, verticalArrangement.platformValue, horizontalAlignment.platformHorizontal, - ) { ColumnScope.Impl(this).content() } + content.toCommonColumnScopeContent() + ) + + +actual typealias PlatformColumnScope = androidx.compose.foundation.layout.ColumnScope //@LayoutScopeMarker actual interface ColumnScope { - val platformValue: PlatformColumnScope + actual val platformValue: PlatformColumnScope @JvmInline - value class Impl(override val platformValue: PlatformColumnScope) : ColumnScope + actual value class Impl(override val platformValue: PlatformColumnScope) : ColumnScope @Stable actual fun Modifier.weight( diff --git a/compose-multiplatform-common/src/androidxCommonMain/kotlin/com/huanshankeji/compose/foundation/layout/Row.androidxCommon.kt b/compose-multiplatform-common/src/androidxCommonMain/kotlin/com/huanshankeji/compose/foundation/layout/Row.androidxCommon.kt index 8e4b8e46..56babac8 100644 --- a/compose-multiplatform-common/src/androidxCommonMain/kotlin/com/huanshankeji/compose/foundation/layout/Row.androidxCommon.kt +++ b/compose-multiplatform-common/src/androidxCommonMain/kotlin/com/huanshankeji/compose/foundation/layout/Row.androidxCommon.kt @@ -6,7 +6,6 @@ import androidx.compose.runtime.Stable import com.huanshankeji.compose.ui.Alignment import com.huanshankeji.compose.ui.Modifier import kotlin.jvm.JvmInline -import androidx.compose.foundation.layout.RowScope as PlatformRowScope @Composable actual fun Row( @@ -22,12 +21,15 @@ actual fun Row( content.toPlatformRowScopeContent(), ) + +actual typealias PlatformRowScope = androidx.compose.foundation.layout.RowScope + //@LayoutScopeMarker actual interface RowScope { - val platformValue: PlatformRowScope + actual val platformValue: PlatformRowScope @JvmInline - value class Impl(override val platformValue: PlatformRowScope) : RowScope + actual value class Impl(override val platformValue: PlatformRowScope) : RowScope actual fun Modifier.weight( @FloatRange(from = 0.0, fromInclusive = false) @@ -39,7 +41,3 @@ actual interface RowScope { actual fun Modifier.align(alignment: Alignment.Vertical): Modifier = with(platformValue) { platformModify { align(alignment.platformHorizontal) } } } - - -fun (@Composable (RowScope.() -> Unit)).toPlatformRowScopeContent(): @Composable PlatformRowScope.() -> Unit = - { RowScope.Impl(this).(this@toPlatformRowScopeContent)() } diff --git a/compose-multiplatform-common/src/commonMain/kotlin/com/huanshankeji/compose/Content.kt b/compose-multiplatform-common/src/commonMain/kotlin/com/huanshankeji/compose/Content.kt new file mode 100644 index 00000000..a289f126 --- /dev/null +++ b/compose-multiplatform-common/src/commonMain/kotlin/com/huanshankeji/compose/Content.kt @@ -0,0 +1,7 @@ +package com.huanshankeji.compose + +/* +// This API seems to reduce the readability of code +fun (@Composable () -> Unit).toContentWithoutScope(): @Composable Scope.() -> Unit = + { this@toContentWithoutScope() } +*/ diff --git a/compose-multiplatform-common/src/commonMain/kotlin/com/huanshankeji/compose/foundation/layout/Column.kt b/compose-multiplatform-common/src/commonMain/kotlin/com/huanshankeji/compose/foundation/layout/Column.kt index 50ca8bca..0691a84e 100644 --- a/compose-multiplatform-common/src/commonMain/kotlin/com/huanshankeji/compose/foundation/layout/Column.kt +++ b/compose-multiplatform-common/src/commonMain/kotlin/com/huanshankeji/compose/foundation/layout/Column.kt @@ -5,6 +5,7 @@ import androidx.compose.runtime.Composable import androidx.compose.runtime.Stable import com.huanshankeji.compose.ui.Alignment import com.huanshankeji.compose.ui.Modifier +import kotlin.jvm.JvmInline @Composable expect fun Column( @@ -14,8 +15,16 @@ expect fun Column( content: @Composable ColumnScope.() -> Unit ) + +expect interface PlatformColumnScope + //@LayoutScopeMarker expect interface ColumnScope { + val platformValue: PlatformColumnScope + + @JvmInline + value class Impl(override val platformValue: PlatformColumnScope) : ColumnScope + @Stable open fun Modifier.weight( @FloatRange(from = 0.0, fromInclusive = false) @@ -25,3 +34,6 @@ expect interface ColumnScope { @Stable open fun Modifier.align(alignment: Alignment.Horizontal): Modifier } + +fun (@Composable (ColumnScope.() -> Unit)).toCommonColumnScopeContent(): @Composable PlatformColumnScope.() -> Unit = + { ColumnScope.Impl(this).this@toCommonColumnScopeContent() } diff --git a/compose-multiplatform-common/src/commonMain/kotlin/com/huanshankeji/compose/foundation/layout/Row.kt b/compose-multiplatform-common/src/commonMain/kotlin/com/huanshankeji/compose/foundation/layout/Row.kt index 1608d327..f61df2ca 100644 --- a/compose-multiplatform-common/src/commonMain/kotlin/com/huanshankeji/compose/foundation/layout/Row.kt +++ b/compose-multiplatform-common/src/commonMain/kotlin/com/huanshankeji/compose/foundation/layout/Row.kt @@ -14,8 +14,15 @@ expect fun Row( content: @Composable RowScope.() -> Unit ) + +expect interface PlatformRowScope + //@LayoutScopeMarker expect interface RowScope { + val platformValue: PlatformRowScope + + value class Impl(override val platformValue: PlatformRowScope) : RowScope + @Stable open fun Modifier.weight( @FloatRange(from = 0.0, fromInclusive = false) @@ -25,3 +32,6 @@ expect interface RowScope { @Stable open fun Modifier.align(alignment: Alignment.Vertical): Modifier } + +fun (@Composable (RowScope.() -> Unit)).toPlatformRowScopeContent(): @Composable PlatformRowScope.() -> Unit = + { RowScope.Impl(this).this@toPlatformRowScopeContent() } diff --git a/compose-multiplatform-common/src/jsMain/kotlin/com/huanshankeji/compose/foundation/layout/Column.js.kt b/compose-multiplatform-common/src/jsMain/kotlin/com/huanshankeji/compose/foundation/layout/Column.js.kt index 2f4996ec..be3b9ea2 100644 --- a/compose-multiplatform-common/src/jsMain/kotlin/com/huanshankeji/compose/foundation/layout/Column.js.kt +++ b/compose-multiplatform-common/src/jsMain/kotlin/com/huanshankeji/compose/foundation/layout/Column.js.kt @@ -8,7 +8,6 @@ import com.huanshankeji.compose.ui.Modifier import com.huanshankeji.compose.ui.PlatformModifier import com.huanshankeji.kobweb.compose.ui.modifiers.sizeFitContent import com.varabyte.kobweb.compose.foundation.layout.LayoutScopeMarker -import com.varabyte.kobweb.compose.foundation.layout.ColumnScope as PlatformColumnScope @Composable actual fun Column( @@ -23,15 +22,19 @@ actual fun Column( .sizeFitContent() // "fit-content" is added to make it consistent with the `androidx` one .then(modifier.platformModifier), verticalArrangement.platformValue, - horizontalAlignment.platformValue - ) { ColumnScope.Impl(this).content() } + horizontalAlignment.platformValue, + content = content.toCommonColumnScopeContent() + ) } + +actual typealias PlatformColumnScope = com.varabyte.kobweb.compose.foundation.layout.ColumnScope + @LayoutScopeMarker actual interface ColumnScope { - val platformValue: PlatformColumnScope + actual val platformValue: PlatformColumnScope - value class Impl(override val platformValue: PlatformColumnScope) : ColumnScope + actual value class Impl(override val platformValue: PlatformColumnScope) : ColumnScope @Stable actual fun Modifier.weight( diff --git a/compose-multiplatform-common/src/jsMain/kotlin/com/huanshankeji/compose/foundation/layout/Row.js.kt b/compose-multiplatform-common/src/jsMain/kotlin/com/huanshankeji/compose/foundation/layout/Row.js.kt index 2b4b1e9d..04b1e3a5 100644 --- a/compose-multiplatform-common/src/jsMain/kotlin/com/huanshankeji/compose/foundation/layout/Row.js.kt +++ b/compose-multiplatform-common/src/jsMain/kotlin/com/huanshankeji/compose/foundation/layout/Row.js.kt @@ -8,7 +8,6 @@ import com.huanshankeji.compose.ui.Modifier import com.huanshankeji.compose.ui.PlatformModifier import com.huanshankeji.kobweb.compose.ui.modifiers.sizeFitContent import com.varabyte.kobweb.compose.foundation.layout.LayoutScopeMarker -import com.varabyte.kobweb.compose.foundation.layout.RowScope as PlatformRowScope @Composable actual fun Row( @@ -28,11 +27,14 @@ actual fun Row( ) } + +actual typealias PlatformRowScope = com.varabyte.kobweb.compose.foundation.layout.RowScope + @LayoutScopeMarker actual interface RowScope { - val platformValue: PlatformRowScope + actual val platformValue: PlatformRowScope - value class Impl(override val platformValue: PlatformRowScope) : RowScope + actual value class Impl(override val platformValue: PlatformRowScope) : RowScope @Stable actual fun Modifier.weight( @@ -45,7 +47,3 @@ actual interface RowScope { actual fun Modifier.align(alignment: Alignment.Vertical): Modifier = with(platformValue) { platformModify { align(alignment.platformValue) } } } - - -fun (@Composable (RowScope.() -> Unit)).toPlatformRowScopeContent(): @Composable PlatformRowScope.() -> Unit = - { RowScope.Impl(this).(this@toPlatformRowScopeContent)() } diff --git a/compose-multiplatform-material3/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material3/Card.androidxCommon.kt b/compose-multiplatform-material3/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material3/Card.androidxCommon.kt new file mode 100644 index 00000000..7eb04415 --- /dev/null +++ b/compose-multiplatform-material3/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material3/Card.androidxCommon.kt @@ -0,0 +1,18 @@ +package com.huanshankeji.compose.material3 + +import androidx.compose.runtime.Composable +import com.huanshankeji.compose.foundation.layout.ColumnScope +import com.huanshankeji.compose.foundation.layout.toCommonColumnScopeContent +import com.huanshankeji.compose.ui.Modifier + +@Composable +actual fun Card(modifier: Modifier, content: @Composable ColumnScope.() -> Unit) = + androidx.compose.material3.Card(modifier.platformModifier, content = content.toCommonColumnScopeContent()) + +@Composable +actual fun ElevatedCard(modifier: Modifier, content: @Composable ColumnScope.() -> Unit) = + androidx.compose.material3.ElevatedCard(modifier.platformModifier, content = content.toCommonColumnScopeContent()) + +@Composable +actual fun OutlinedCard(modifier: Modifier, content: @Composable ColumnScope.() -> Unit) = + androidx.compose.material3.OutlinedCard(modifier.platformModifier, content = content.toCommonColumnScopeContent()) diff --git a/compose-multiplatform-material3/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material3/ext/Card.androidxCommon.kt b/compose-multiplatform-material3/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material3/ext/Card.androidxCommon.kt new file mode 100644 index 00000000..0b887757 --- /dev/null +++ b/compose-multiplatform-material3/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material3/ext/Card.androidxCommon.kt @@ -0,0 +1,16 @@ +package com.huanshankeji.compose.material3.ext + +import androidx.compose.runtime.Composable +import com.huanshankeji.compose.ui.Modifier + +@Composable +actual fun Card(modifier: Modifier, content: @Composable () -> Unit) = + com.huanshankeji.compose.material3.Card(modifier) { content() } + +@Composable +actual fun ElevatedCard(modifier: Modifier, content: @Composable () -> Unit) = + com.huanshankeji.compose.material3.ElevatedCard(modifier) { content() } + +@Composable +actual fun OutlinedCard(modifier: Modifier, content: @Composable () -> Unit) = + com.huanshankeji.compose.material3.OutlinedCard(modifier) { content() } diff --git a/compose-multiplatform-material3/src/commonMain/kotlin/com/huanshankeji/compose/material3/Card.kt b/compose-multiplatform-material3/src/commonMain/kotlin/com/huanshankeji/compose/material3/Card.kt new file mode 100644 index 00000000..cfce45ea --- /dev/null +++ b/compose-multiplatform-material3/src/commonMain/kotlin/com/huanshankeji/compose/material3/Card.kt @@ -0,0 +1,36 @@ +package com.huanshankeji.compose.material3 + +import androidx.compose.runtime.Composable +import com.huanshankeji.compose.foundation.layout.ColumnScope +import com.huanshankeji.compose.material3.ext.Card +import com.huanshankeji.compose.ui.Modifier + +@Composable +expect fun Card( + modifier: Modifier = Modifier, + content: @Composable ColumnScope.() -> Unit +) + +/** + * An alias for [Card]. + */ +@Composable +fun FilledCard( + modifier: Modifier = Modifier, + content: @Composable ColumnScope.() -> Unit +) = + Card(modifier, content) + +// TODO clickable cards + +@Composable +expect fun ElevatedCard( + modifier: Modifier = Modifier, + content: @Composable ColumnScope.() -> Unit +) + +@Composable +expect fun OutlinedCard( + modifier: Modifier = Modifier, + content: @Composable ColumnScope.() -> Unit +) diff --git a/compose-multiplatform-material3/src/commonMain/kotlin/com/huanshankeji/compose/material3/ext/Card.kt b/compose-multiplatform-material3/src/commonMain/kotlin/com/huanshankeji/compose/material3/ext/Card.kt new file mode 100644 index 00000000..66adbd9c --- /dev/null +++ b/compose-multiplatform-material3/src/commonMain/kotlin/com/huanshankeji/compose/material3/ext/Card.kt @@ -0,0 +1,32 @@ +package com.huanshankeji.compose.material3.ext + +import androidx.compose.runtime.Composable +import com.huanshankeji.compose.ui.Modifier + +@Composable +expect fun Card( + modifier: Modifier = Modifier, + content: @Composable () -> Unit +) + +/** + * An alias for [Card]. + */ +@Composable +fun FilledCard( + modifier: Modifier = Modifier, + content: @Composable () -> Unit +) = + Card(modifier, content) + +@Composable +expect fun ElevatedCard( + modifier: Modifier = Modifier, + content: @Composable () -> Unit +) + +@Composable +expect fun OutlinedCard( + modifier: Modifier = Modifier, + content: @Composable () -> Unit +) diff --git a/compose-multiplatform-material3/src/jsMain/kotlin/com/huanshankeji/compose/material3/Card.js.kt b/compose-multiplatform-material3/src/jsMain/kotlin/com/huanshankeji/compose/material3/Card.js.kt new file mode 100644 index 00000000..4afc775b --- /dev/null +++ b/compose-multiplatform-material3/src/jsMain/kotlin/com/huanshankeji/compose/material3/Card.js.kt @@ -0,0 +1,34 @@ +package com.huanshankeji.compose.material3 + +import androidx.compose.runtime.Composable +import com.huanshankeji.compose.foundation.layout.ColumnScope +import com.huanshankeji.compose.foundation.layout.toCommonColumnScopeContent +import com.huanshankeji.compose.ui.Modifier +import com.varabyte.kobweb.compose.foundation.layout.Column + +@Composable +actual fun Card( + modifier: Modifier, + content: @Composable ColumnScope.() -> Unit +) = + com.huanshankeji.compose.material3.ext.Card(modifier) { + Column(content = content.toCommonColumnScopeContent()) + } + +@Composable +actual fun ElevatedCard( + modifier: Modifier, + content: @Composable ColumnScope.() -> Unit +) = + com.huanshankeji.compose.material3.ext.ElevatedCard(modifier) { + Column(content = content.toCommonColumnScopeContent()) + } + +@Composable +actual fun OutlinedCard( + modifier: Modifier, + content: @Composable ColumnScope.() -> Unit +) = + com.huanshankeji.compose.material3.ext.OutlinedCard(modifier) { + Column(content = content.toCommonColumnScopeContent()) + } diff --git a/compose-multiplatform-material3/src/jsMain/kotlin/com/huanshankeji/compose/material3/ext/Card.js.kt b/compose-multiplatform-material3/src/jsMain/kotlin/com/huanshankeji/compose/material3/ext/Card.js.kt new file mode 100644 index 00000000..14f54cb3 --- /dev/null +++ b/compose-multiplatform-material3/src/jsMain/kotlin/com/huanshankeji/compose/material3/ext/Card.js.kt @@ -0,0 +1,24 @@ +package com.huanshankeji.compose.material3.ext + +import androidx.compose.runtime.Composable +import com.huanshankeji.compose.html.material3.MaterialWebLabsApi +import com.huanshankeji.compose.html.material3.MdElevatedCard +import com.huanshankeji.compose.html.material3.MdFilledCard +import com.huanshankeji.compose.html.material3.MdOutlinedCard +import com.huanshankeji.compose.ui.Modifier +import com.varabyte.kobweb.compose.ui.toAttrs + +@Composable +actual fun Card(modifier: Modifier, content: @Composable () -> Unit) = + @OptIn(MaterialWebLabsApi::class) + MdFilledCard(modifier.platformModifier.toAttrs()) { content() } + +@Composable +actual fun ElevatedCard(modifier: Modifier, content: @Composable () -> Unit) = + @OptIn(MaterialWebLabsApi::class) + MdElevatedCard(modifier.platformModifier.toAttrs()) { content() } + +@Composable +actual fun OutlinedCard(modifier: Modifier, content: @Composable () -> Unit) = + @OptIn(MaterialWebLabsApi::class) + MdOutlinedCard(modifier.platformModifier.toAttrs()) { content() } diff --git a/demo/src/commonMain/kotlin/com/huanshankeji/compose/material/demo/App.kt b/demo/src/commonMain/kotlin/com/huanshankeji/compose/material/demo/App.kt index d1dfa540..90513c41 100644 --- a/demo/src/commonMain/kotlin/com/huanshankeji/compose/material/demo/App.kt +++ b/demo/src/commonMain/kotlin/com/huanshankeji/compose/material/demo/App.kt @@ -4,6 +4,9 @@ import androidx.compose.runtime.Composable import androidx.compose.ui.unit.dp import com.huanshankeji.compose.foundation.layout.Box import com.huanshankeji.compose.foundation.layout.Row +import com.huanshankeji.compose.foundation.rememberScrollState +import com.huanshankeji.compose.foundation.verticalScroll +import com.huanshankeji.compose.layout.padding import com.huanshankeji.compose.ui.Modifier internal enum class RadioButtonState { @@ -12,17 +15,21 @@ internal enum class RadioButtonState { val listSize = 160.dp +fun Modifier.contentPadding() = padding(16.dp) +val contentPaddingModifier = Modifier.contentPadding() + @Composable fun App() { - Row { - Box(Modifier.weight(1f)) { - Common() - } - Box(Modifier.weight(1f)) { - Material2() - } + Row(/*Modifier.height(720.dp)*/) { + @Composable + fun subDemoModifier() = + Modifier.weight(1f).verticalScroll(rememberScrollState()) + + Common(subDemoModifier()) + // Putting the scroll modifier in the `Box` causes `java.lang.IllegalArgumentException: Can't represent a size of 2147483577 in Constraints`. Box(Modifier.weight(1f)) { - Material3() + Material2(Modifier.verticalScroll(rememberScrollState())) } + Material3(subDemoModifier()) } } diff --git a/demo/src/commonMain/kotlin/com/huanshankeji/compose/material/demo/Common.kt b/demo/src/commonMain/kotlin/com/huanshankeji/compose/material/demo/Common.kt index 8558535f..54120689 100644 --- a/demo/src/commonMain/kotlin/com/huanshankeji/compose/material/demo/Common.kt +++ b/demo/src/commonMain/kotlin/com/huanshankeji/compose/material/demo/Common.kt @@ -21,8 +21,8 @@ import com.huanshankeji.compose.ui.Modifier import com.huanshankeji.compose.ui.graphics.Color @Composable -fun Common() { - Column { +fun Common(modifier: Modifier) { + Column(modifier) { BasicText("basic text 1") BasicText("basic text 2") diff --git a/demo/src/commonMain/kotlin/com/huanshankeji/compose/material/demo/Material2.kt b/demo/src/commonMain/kotlin/com/huanshankeji/compose/material/demo/Material2.kt index 55b5b641..eb7186c7 100644 --- a/demo/src/commonMain/kotlin/com/huanshankeji/compose/material/demo/Material2.kt +++ b/demo/src/commonMain/kotlin/com/huanshankeji/compose/material/demo/Material2.kt @@ -13,7 +13,6 @@ import com.huanshankeji.compose.foundation.text.input.KeyboardCapitalization import com.huanshankeji.compose.foundation.text.input.KeyboardType import com.huanshankeji.compose.layout.height import com.huanshankeji.compose.layout.padding -import com.huanshankeji.compose.layout.width import com.huanshankeji.compose.material.icons.Icons import com.huanshankeji.compose.material.icons.filled.Add import com.huanshankeji.compose.material.icons.filled.Menu @@ -29,7 +28,8 @@ import com.huanshankeji.compose.ui.graphics.Color import com.huanshankeji.compose.material2.ext.Button as ExtButton @Composable -fun Material2() { +fun Material2(modifier: Modifier) { + // It seems the modifier can't be set on `TopAppBarScaffold` or a box wrapping it TopAppBarScaffold({ Text("Compose Multiplatform Material demo") }, navigationIcon = { @@ -37,8 +37,8 @@ fun Material2() { }, actions = { MaterialIconActionButton({}, Icons.Default.Search, "search") }) { - Card(Modifier.padding(16.dp).height(800.dp).width(400.dp)) { - Column(Modifier.padding(16.dp).background(Color(0xF8, 0xF8, 0xF8, 0xFF))) { + Card(modifier.contentPadding()) { + Column(contentPaddingModifier.background(Color(0xF8, 0xF8, 0xF8, 0xFF))) { Text("Material text") var count by remember { mutableStateOf(0) } diff --git a/demo/src/commonMain/kotlin/com/huanshankeji/compose/material/demo/Material3.kt b/demo/src/commonMain/kotlin/com/huanshankeji/compose/material/demo/Material3.kt index 3c70a945..ffcc2d04 100644 --- a/demo/src/commonMain/kotlin/com/huanshankeji/compose/material/demo/Material3.kt +++ b/demo/src/commonMain/kotlin/com/huanshankeji/compose/material/demo/Material3.kt @@ -17,14 +17,17 @@ import com.huanshankeji.compose.material.icons.filled.Menu import com.huanshankeji.compose.material.icons.filled.Remove import com.huanshankeji.compose.material3.* import com.huanshankeji.compose.material3.ext.* +import com.huanshankeji.compose.material3.ext.Card +import com.huanshankeji.compose.material3.ext.ElevatedCard +import com.huanshankeji.compose.material3.ext.OutlinedCard import com.huanshankeji.compose.material3.lazy.ext.List import com.huanshankeji.compose.material3.lazy.ext.ListItemComponents import com.huanshankeji.compose.ui.Modifier import com.huanshankeji.compose.material3.Button as RowScopeButton @Composable -fun Material3() { - Column { +fun Material3(modifier: Modifier) { + Column(modifier) { var count by remember { mutableStateOf(0) } val onClick: () -> Unit = { count++ } val buttonContent: @Composable () -> Unit = { @@ -155,5 +158,11 @@ fun Material3() { content(index.toString()) } } + + Row { + Card { Text("card", contentPaddingModifier) } + ElevatedCard { Text("elevated card", contentPaddingModifier) } + OutlinedCard { Text("outlined card", contentPaddingModifier) } + } } } From d4de7c317444c537838f43f46bd9dff20a914a7d Mon Sep 17 00:00:00 2001 From: Shreck Ye Date: Thu, 9 May 2024 09:42:58 +0800 Subject: [PATCH 70/75] Extract `Modifier.toAttrs` --- .../huanshankeji/compose/foundation/layout/Spacer.js.kt | 4 ++-- .../huanshankeji/compose/foundation/text/BasicText.js.kt | 4 ++-- .../kotlin/com/huanshankeji/compose/ui/Modifier.js.kt | 6 ++++++ .../com/huanshankeji/compose/material2/Button.js.kt | 4 ++-- .../com/huanshankeji/compose/material2/Checkbox.js.kt | 4 ++-- .../com/huanshankeji/compose/material2/Divider.js.kt | 4 ++-- .../kotlin/com/huanshankeji/compose/material2/Icon.js.kt | 4 ++-- .../com/huanshankeji/compose/material2/IconButton.js.kt | 4 ++-- .../com/huanshankeji/compose/material2/Switch.js.kt | 4 ++-- .../com/huanshankeji/compose/material2/ext/Radio.js.kt | 6 +++--- .../huanshankeji/compose/material2/ext/TextField.js.kt | 6 +++--- .../compose/material2/ext/TopAppBarScaffold.js.kt | 4 ++-- .../com/huanshankeji/compose/material3/Checkbox.js.kt | 4 ++-- .../com/huanshankeji/compose/material3/CommonButton.js.kt | 4 ++-- .../kotlin/com/huanshankeji/compose/material3/Icon.js.kt | 4 ++-- .../com/huanshankeji/compose/material3/IconButton.js.kt | 4 ++-- .../com/huanshankeji/compose/material3/Switch.js.kt | 4 ++-- .../com/huanshankeji/compose/material3/ext/Card.js.kt | 8 ++++---- .../huanshankeji/compose/material3/ext/TextField.js.kt | 4 ++-- .../huanshankeji/compose/material3/lazy/ext/List.js.kt | 3 ++- 20 files changed, 48 insertions(+), 41 deletions(-) diff --git a/compose-multiplatform-common/src/jsMain/kotlin/com/huanshankeji/compose/foundation/layout/Spacer.js.kt b/compose-multiplatform-common/src/jsMain/kotlin/com/huanshankeji/compose/foundation/layout/Spacer.js.kt index 49b00149..2d2377cb 100644 --- a/compose-multiplatform-common/src/jsMain/kotlin/com/huanshankeji/compose/foundation/layout/Spacer.js.kt +++ b/compose-multiplatform-common/src/jsMain/kotlin/com/huanshankeji/compose/foundation/layout/Spacer.js.kt @@ -2,12 +2,12 @@ package com.huanshankeji.compose.foundation.layout import androidx.compose.runtime.Composable import com.huanshankeji.compose.ui.Modifier -import com.varabyte.kobweb.compose.ui.toAttrs +import com.huanshankeji.compose.ui.toAttrs import org.jetbrains.compose.web.dom.Div @Composable actual fun Spacer(modifier: Modifier) { AddKobwebComposeStyleSheet() - Div(attrs = modifier.platformModifier.toAttrs { classes("kobweb-spacer") }) + Div(attrs = modifier.toAttrs { classes("kobweb-spacer") }) //com.varabyte.kobweb.compose.foundation.layout.Spacer() // use this when `Modifier` is supported } diff --git a/compose-multiplatform-common/src/jsMain/kotlin/com/huanshankeji/compose/foundation/text/BasicText.js.kt b/compose-multiplatform-common/src/jsMain/kotlin/com/huanshankeji/compose/foundation/text/BasicText.js.kt index dc0fe0ce..b038591c 100644 --- a/compose-multiplatform-common/src/jsMain/kotlin/com/huanshankeji/compose/foundation/text/BasicText.js.kt +++ b/compose-multiplatform-common/src/jsMain/kotlin/com/huanshankeji/compose/foundation/text/BasicText.js.kt @@ -2,7 +2,7 @@ package com.huanshankeji.compose.foundation.text import androidx.compose.runtime.Composable import com.huanshankeji.compose.ui.Modifier -import com.varabyte.kobweb.compose.ui.toAttrs +import com.huanshankeji.compose.ui.toAttrs import org.jetbrains.compose.web.dom.Span import org.jetbrains.compose.web.dom.Text @@ -17,4 +17,4 @@ actual fun BasicText(text: String) = @Composable actual fun BasicText(text: String, modifier: Modifier) = - Span(modifier.platformModifier.toAttrs()) { Text(text) } + Span(modifier.toAttrs()) { Text(text) } diff --git a/compose-multiplatform-common/src/jsMain/kotlin/com/huanshankeji/compose/ui/Modifier.js.kt b/compose-multiplatform-common/src/jsMain/kotlin/com/huanshankeji/compose/ui/Modifier.js.kt index a4507fc2..4f0f073d 100644 --- a/compose-multiplatform-common/src/jsMain/kotlin/com/huanshankeji/compose/ui/Modifier.js.kt +++ b/compose-multiplatform-common/src/jsMain/kotlin/com/huanshankeji/compose/ui/Modifier.js.kt @@ -1,5 +1,8 @@ package com.huanshankeji.compose.ui +import com.varabyte.kobweb.compose.ui.toAttrs +import org.jetbrains.compose.web.attributes.AttrsScope +import org.w3c.dom.Element import com.varabyte.kobweb.compose.ui.Modifier as PlatformModifier typealias PlatformModifier = PlatformModifier @@ -34,3 +37,6 @@ actual interface Modifier { fun PlatformModifier.toCommonModifier() = Modifier.Impl(this) + +fun > Modifier.toAttrs(finalHandler: (A.() -> Unit)? = null): A.() -> Unit = + platformModifier.toAttrs(finalHandler) diff --git a/compose-multiplatform-material2/src/jsMain/kotlin/com/huanshankeji/compose/material2/Button.js.kt b/compose-multiplatform-material2/src/jsMain/kotlin/com/huanshankeji/compose/material2/Button.js.kt index 179e261f..a131af88 100644 --- a/compose-multiplatform-material2/src/jsMain/kotlin/com/huanshankeji/compose/material2/Button.js.kt +++ b/compose-multiplatform-material2/src/jsMain/kotlin/com/huanshankeji/compose/material2/Button.js.kt @@ -6,7 +6,7 @@ import com.huanshankeji.compose.foundation.layout.RowScope import com.huanshankeji.compose.material2.ext.ButtonType import com.huanshankeji.compose.material2.ext.toMDCButtonType import com.huanshankeji.compose.ui.Modifier -import com.varabyte.kobweb.compose.ui.toAttrs +import com.huanshankeji.compose.ui.toAttrs import dev.petuska.kmdc.button.MDCButton import dev.petuska.kmdc.button.MDCButtonScope import org.w3c.dom.HTMLButtonElement @@ -20,7 +20,7 @@ internal fun CommonButton( ) = MDCButton( buttonType.toMDCButtonType(), - attrs = modifier.platformModifier.toAttrs { + attrs = modifier.toAttrs { onClick { onClick() } }, content = content diff --git a/compose-multiplatform-material2/src/jsMain/kotlin/com/huanshankeji/compose/material2/Checkbox.js.kt b/compose-multiplatform-material2/src/jsMain/kotlin/com/huanshankeji/compose/material2/Checkbox.js.kt index 5c4ef37f..dd84f269 100644 --- a/compose-multiplatform-material2/src/jsMain/kotlin/com/huanshankeji/compose/material2/Checkbox.js.kt +++ b/compose-multiplatform-material2/src/jsMain/kotlin/com/huanshankeji/compose/material2/Checkbox.js.kt @@ -2,7 +2,7 @@ package com.huanshankeji.compose.material2 import androidx.compose.runtime.Composable import com.huanshankeji.compose.ui.Modifier -import com.varabyte.kobweb.compose.ui.toAttrs +import com.huanshankeji.compose.ui.toAttrs import dev.petuska.kmdc.checkbox.MDCCheckbox // https://github.com/mpetuska/kmdc/blob/master/sandbox/src/jsMain/showcases/MDCCheckbox.kt @@ -13,6 +13,6 @@ actual fun Checkbox( modifier: Modifier, enabled: Boolean ) = - MDCCheckbox(checked, !enabled, attrs = modifier.platformModifier.toAttrs { + MDCCheckbox(checked, !enabled, attrs = modifier.toAttrs { onCheckedChange?.let { onInput { it(!checked) } } }) diff --git a/compose-multiplatform-material2/src/jsMain/kotlin/com/huanshankeji/compose/material2/Divider.js.kt b/compose-multiplatform-material2/src/jsMain/kotlin/com/huanshankeji/compose/material2/Divider.js.kt index c2ff8287..f610f20c 100644 --- a/compose-multiplatform-material2/src/jsMain/kotlin/com/huanshankeji/compose/material2/Divider.js.kt +++ b/compose-multiplatform-material2/src/jsMain/kotlin/com/huanshankeji/compose/material2/Divider.js.kt @@ -2,7 +2,7 @@ package com.huanshankeji.compose.material2 import androidx.compose.runtime.Composable import com.huanshankeji.compose.ui.Modifier -import com.varabyte.kobweb.compose.ui.toAttrs +import com.huanshankeji.compose.ui.toAttrs import org.jetbrains.compose.web.dom.Hr // https://developer.mozilla.org/en-US/docs/Web/HTML/Element/hr @@ -10,4 +10,4 @@ import org.jetbrains.compose.web.dom.Hr // see: https://github.com/mpetuska/kmdc/blob/master/katalog/katalog-runtime/src/jsMain/kotlin/layout/Divider.kt @Composable actual fun Divider(modifier: Modifier) = - Hr(modifier.platformModifier.toAttrs()) + Hr(modifier.toAttrs()) diff --git a/compose-multiplatform-material2/src/jsMain/kotlin/com/huanshankeji/compose/material2/Icon.js.kt b/compose-multiplatform-material2/src/jsMain/kotlin/com/huanshankeji/compose/material2/Icon.js.kt index eda10d78..d580c98e 100644 --- a/compose-multiplatform-material2/src/jsMain/kotlin/com/huanshankeji/compose/material2/Icon.js.kt +++ b/compose-multiplatform-material2/src/jsMain/kotlin/com/huanshankeji/compose/material2/Icon.js.kt @@ -5,7 +5,7 @@ import com.huanshankeji.compose.contentDescription import com.huanshankeji.compose.material.icons.Icon import com.huanshankeji.compose.material2.icons.toMDCIcon import com.huanshankeji.compose.ui.Modifier -import com.varabyte.kobweb.compose.ui.toAttrs +import com.huanshankeji.compose.ui.toAttrs import dev.petuska.kmdcx.icons.MDCIconSpan /** @@ -13,6 +13,6 @@ import dev.petuska.kmdcx.icons.MDCIconSpan */ @Composable actual fun Icon(icon: Icon, contentDescription: String?, modifier: Modifier) = - MDCIconSpan(icon.toMDCIcon(), attrs = modifier.platformModifier.toAttrs { + MDCIconSpan(icon.toMDCIcon(), attrs = modifier.toAttrs { contentDescription(contentDescription) }) diff --git a/compose-multiplatform-material2/src/jsMain/kotlin/com/huanshankeji/compose/material2/IconButton.js.kt b/compose-multiplatform-material2/src/jsMain/kotlin/com/huanshankeji/compose/material2/IconButton.js.kt index 462d6aee..be0b2244 100644 --- a/compose-multiplatform-material2/src/jsMain/kotlin/com/huanshankeji/compose/material2/IconButton.js.kt +++ b/compose-multiplatform-material2/src/jsMain/kotlin/com/huanshankeji/compose/material2/IconButton.js.kt @@ -2,7 +2,7 @@ package com.huanshankeji.compose.material2 import androidx.compose.runtime.Composable import com.huanshankeji.compose.ui.Modifier -import com.varabyte.kobweb.compose.ui.toAttrs +import com.huanshankeji.compose.ui.toAttrs import dev.petuska.kmdc.icon.button.MDCIconButton @Composable @@ -11,7 +11,7 @@ actual fun IconButton( modifier: Modifier, content: @Composable () -> Unit ) = - MDCIconButton(attrs = modifier.platformModifier.toAttrs { + MDCIconButton(attrs = modifier.toAttrs { onClick { onClick() } }) { content() } diff --git a/compose-multiplatform-material2/src/jsMain/kotlin/com/huanshankeji/compose/material2/Switch.js.kt b/compose-multiplatform-material2/src/jsMain/kotlin/com/huanshankeji/compose/material2/Switch.js.kt index af56719f..bd1dcdb1 100644 --- a/compose-multiplatform-material2/src/jsMain/kotlin/com/huanshankeji/compose/material2/Switch.js.kt +++ b/compose-multiplatform-material2/src/jsMain/kotlin/com/huanshankeji/compose/material2/Switch.js.kt @@ -2,7 +2,7 @@ package com.huanshankeji.compose.material2 import androidx.compose.runtime.Composable import com.huanshankeji.compose.ui.Modifier -import com.varabyte.kobweb.compose.ui.toAttrs +import com.huanshankeji.compose.ui.toAttrs import dev.petuska.kmdc.switch.MDCSwitch import org.jetbrains.compose.web.attributes.disabled @@ -16,7 +16,7 @@ internal fun CommonSwitch( modifier: Modifier, enabled: Boolean ) = - MDCSwitch(checked, label, modifier.platformModifier.toAttrs { + MDCSwitch(checked, label, modifier.toAttrs { if (!enabled) disabled() onCheckedChange?.let { onClick { it(!checked) } } }) diff --git a/compose-multiplatform-material2/src/jsMain/kotlin/com/huanshankeji/compose/material2/ext/Radio.js.kt b/compose-multiplatform-material2/src/jsMain/kotlin/com/huanshankeji/compose/material2/ext/Radio.js.kt index ff32f390..8dd668f7 100644 --- a/compose-multiplatform-material2/src/jsMain/kotlin/com/huanshankeji/compose/material2/ext/Radio.js.kt +++ b/compose-multiplatform-material2/src/jsMain/kotlin/com/huanshankeji/compose/material2/ext/Radio.js.kt @@ -2,7 +2,7 @@ package com.huanshankeji.compose.material2.ext import androidx.compose.runtime.Composable import com.huanshankeji.compose.ui.Modifier -import com.varabyte.kobweb.compose.ui.toAttrs +import com.huanshankeji.compose.ui.toAttrs import dev.petuska.kmdc.form.field.MDCFormField import dev.petuska.kmdc.radio.MDCRadio @@ -10,12 +10,12 @@ import dev.petuska.kmdc.radio.MDCRadio @Composable actual fun RadioRow(selected: Boolean, label: String, onClick: () -> Unit, modifier: Modifier, enabled: Boolean) = - MDCRadio(selected, disabled = !enabled, label = label, attrs = modifier.platformModifier.toAttrs { + MDCRadio(selected, disabled = !enabled, label = label, attrs = modifier.toAttrs { onClick { onClick() } }) @Composable actual fun RadioGroupRow(modifier: Modifier, content: @Composable () -> Unit) = - MDCFormField(attrs = modifier.platformModifier.toAttrs()) { + MDCFormField(attrs = modifier.toAttrs()) { content() } diff --git a/compose-multiplatform-material2/src/jsMain/kotlin/com/huanshankeji/compose/material2/ext/TextField.js.kt b/compose-multiplatform-material2/src/jsMain/kotlin/com/huanshankeji/compose/material2/ext/TextField.js.kt index 42cde6a1..57792107 100644 --- a/compose-multiplatform-material2/src/jsMain/kotlin/com/huanshankeji/compose/material2/ext/TextField.js.kt +++ b/compose-multiplatform-material2/src/jsMain/kotlin/com/huanshankeji/compose/material2/ext/TextField.js.kt @@ -6,7 +6,7 @@ import com.huanshankeji.compose.foundation.text.KeyboardOptions import com.huanshankeji.compose.foundation.text.attrsFrom import com.huanshankeji.compose.material.icons.Icon import com.huanshankeji.compose.ui.Modifier -import com.varabyte.kobweb.compose.ui.toAttrs +import com.huanshankeji.compose.ui.toAttrs import dev.petuska.kmdc.core.MDCContent import dev.petuska.kmdc.textfield.MDCTextArea import dev.petuska.kmdc.textfield.MDCTextField @@ -37,7 +37,7 @@ fun CommonTextFieldWithMDCContentIcons( label, leadingIcon = leadingIcon, trailingIcon = trailingIcon, - attrs = modifier.platformModifier.toAttrs { + attrs = modifier.toAttrs { onInput { onValueChange(it.value) } attrsFrom(keyboardOptions, keyboardActions) @@ -220,6 +220,6 @@ actual fun TextArea( disabled = !enabled, label = label, rows = lines.toUInt(), - attrs = modifier.platformModifier.toAttrs { + attrs = modifier.toAttrs { onInput { onValueChange(it.value) } }) diff --git a/compose-multiplatform-material2/src/jsMain/kotlin/com/huanshankeji/compose/material2/ext/TopAppBarScaffold.js.kt b/compose-multiplatform-material2/src/jsMain/kotlin/com/huanshankeji/compose/material2/ext/TopAppBarScaffold.js.kt index 94f6faae..d3befae4 100644 --- a/compose-multiplatform-material2/src/jsMain/kotlin/com/huanshankeji/compose/material2/ext/TopAppBarScaffold.js.kt +++ b/compose-multiplatform-material2/src/jsMain/kotlin/com/huanshankeji/compose/material2/ext/TopAppBarScaffold.js.kt @@ -4,7 +4,7 @@ import androidx.compose.runtime.Composable import com.huanshankeji.compose.contentDescription import com.huanshankeji.compose.material.icons.Icon import com.huanshankeji.compose.ui.Modifier -import com.varabyte.kobweb.compose.ui.toAttrs +import com.huanshankeji.compose.ui.toAttrs import dev.petuska.kmdc.top.app.bar.* import dev.petuska.kmdcx.icons.mdcIcon import org.jetbrains.compose.web.dom.Text @@ -44,7 +44,7 @@ actual fun TopAppBarScaffold( content: @Composable () -> Unit ) = MDCTopAppBar { - TopAppBar(topAppBarModifier.platformModifier.toAttrs()) { + TopAppBar(topAppBarModifier.toAttrs()) { Row { Section(align = MDCTopAppBarSectionAlign.Start) { navigationIcon?.let { NavigationIconScope(this@Section).it() } diff --git a/compose-multiplatform-material3/src/jsMain/kotlin/com/huanshankeji/compose/material3/Checkbox.js.kt b/compose-multiplatform-material3/src/jsMain/kotlin/com/huanshankeji/compose/material3/Checkbox.js.kt index f42709e3..f2bc899c 100644 --- a/compose-multiplatform-material3/src/jsMain/kotlin/com/huanshankeji/compose/material3/Checkbox.js.kt +++ b/compose-multiplatform-material3/src/jsMain/kotlin/com/huanshankeji/compose/material3/Checkbox.js.kt @@ -3,10 +3,10 @@ package com.huanshankeji.compose.material3 import androidx.compose.runtime.Composable import com.huanshankeji.compose.html.material3.MdCheckbox import com.huanshankeji.compose.ui.Modifier +import com.huanshankeji.compose.ui.toAttrs import com.huanshankeji.compose.web.attributes.ext.onInput import com.huanshankeji.compose.web.attributes.isFalseOrNull import com.huanshankeji.compose.web.attributes.isTrueOrNull -import com.varabyte.kobweb.compose.ui.toAttrs @Composable actual fun Checkbox( @@ -18,7 +18,7 @@ actual fun Checkbox( MdCheckbox( checked.isTrueOrNull(), enabled.isFalseOrNull(), - attrs = modifier.platformModifier.toAttrs { + attrs = modifier.toAttrs { /* Use `onInput` here because it wraps an `input` element. Also see: https://stackoverflow.com/questions/58016503/click-vs-input-vs-change-for-checkboxes diff --git a/compose-multiplatform-material3/src/jsMain/kotlin/com/huanshankeji/compose/material3/CommonButton.js.kt b/compose-multiplatform-material3/src/jsMain/kotlin/com/huanshankeji/compose/material3/CommonButton.js.kt index 54e66b35..97aa4e1f 100644 --- a/compose-multiplatform-material3/src/jsMain/kotlin/com/huanshankeji/compose/material3/CommonButton.js.kt +++ b/compose-multiplatform-material3/src/jsMain/kotlin/com/huanshankeji/compose/material3/CommonButton.js.kt @@ -1,11 +1,11 @@ package com.huanshankeji.compose.material3 import com.huanshankeji.compose.ui.Modifier +import com.huanshankeji.compose.ui.toAttrs import com.huanshankeji.compose.web.attributes.Attrs -import com.varabyte.kobweb.compose.ui.toAttrs import org.w3c.dom.HTMLElement internal fun Modifier.toCommonButtonAttrs(onClick: () -> Unit): Attrs = - platformModifier.toAttrs { + toAttrs { onClick { onClick() } } diff --git a/compose-multiplatform-material3/src/jsMain/kotlin/com/huanshankeji/compose/material3/Icon.js.kt b/compose-multiplatform-material3/src/jsMain/kotlin/com/huanshankeji/compose/material3/Icon.js.kt index 34de0b29..ba60dcef 100644 --- a/compose-multiplatform-material3/src/jsMain/kotlin/com/huanshankeji/compose/material3/Icon.js.kt +++ b/compose-multiplatform-material3/src/jsMain/kotlin/com/huanshankeji/compose/material3/Icon.js.kt @@ -5,7 +5,7 @@ import com.huanshankeji.compose.contentDescription import com.huanshankeji.compose.html.material3.MdIcon import com.huanshankeji.compose.material.icons.Icon import com.huanshankeji.compose.ui.Modifier -import com.varabyte.kobweb.compose.ui.toAttrs +import com.huanshankeji.compose.ui.toAttrs @Composable actual fun Icon( @@ -13,6 +13,6 @@ actual fun Icon( contentDescription: String?, modifier: Modifier ) = - MdIcon(attrs = modifier.platformModifier.toAttrs { + MdIcon(attrs = modifier.toAttrs { contentDescription(contentDescription) }, materialIconName = icon.name) diff --git a/compose-multiplatform-material3/src/jsMain/kotlin/com/huanshankeji/compose/material3/IconButton.js.kt b/compose-multiplatform-material3/src/jsMain/kotlin/com/huanshankeji/compose/material3/IconButton.js.kt index b997c461..9113e953 100644 --- a/compose-multiplatform-material3/src/jsMain/kotlin/com/huanshankeji/compose/material3/IconButton.js.kt +++ b/compose-multiplatform-material3/src/jsMain/kotlin/com/huanshankeji/compose/material3/IconButton.js.kt @@ -5,19 +5,19 @@ import com.huanshankeji.compose.foundation.layout.Box import com.huanshankeji.compose.html.material3.* import com.huanshankeji.compose.ui.Modifier import com.huanshankeji.compose.ui.PlatformModifier +import com.huanshankeji.compose.ui.toAttrs import com.huanshankeji.compose.ui.toCommonModifier import com.huanshankeji.compose.web.attributes.ext.onInput import com.huanshankeji.compose.web.attributes.isFalseOrNull import com.huanshankeji.compose.web.attributes.isTrueOrNull import com.varabyte.kobweb.compose.ui.attrsModifier -import com.varabyte.kobweb.compose.ui.toAttrs import org.jetbrains.compose.web.attributes.AttrsScope import org.w3c.dom.HTMLElement internal fun Modifier.toCommonIconToggleButtonAttrs( checked: Boolean, onCheckedChange: (Boolean) -> Unit ): AttrsScope.() -> Unit = - platformModifier.toAttrs { + toAttrs { // note that `onInput` is used here onInput { onCheckedChange(!checked) } } diff --git a/compose-multiplatform-material3/src/jsMain/kotlin/com/huanshankeji/compose/material3/Switch.js.kt b/compose-multiplatform-material3/src/jsMain/kotlin/com/huanshankeji/compose/material3/Switch.js.kt index 325cf8fb..c682c80b 100644 --- a/compose-multiplatform-material3/src/jsMain/kotlin/com/huanshankeji/compose/material3/Switch.js.kt +++ b/compose-multiplatform-material3/src/jsMain/kotlin/com/huanshankeji/compose/material3/Switch.js.kt @@ -3,10 +3,10 @@ package com.huanshankeji.compose.material3 import androidx.compose.runtime.Composable import com.huanshankeji.compose.html.material3.MdSwitch import com.huanshankeji.compose.ui.Modifier +import com.huanshankeji.compose.ui.toAttrs import com.huanshankeji.compose.web.attributes.ext.onInput import com.huanshankeji.compose.web.attributes.isFalseOrNull import com.huanshankeji.compose.web.attributes.isTrueOrNull -import com.varabyte.kobweb.compose.ui.toAttrs @Composable actual fun Switch( @@ -18,6 +18,6 @@ actual fun Switch( MdSwitch( enabled.isFalseOrNull(), checked.isTrueOrNull(), - attrs = modifier.platformModifier.toAttrs { + attrs = modifier.toAttrs { onCheckedChange?.let { onInput { onCheckedChange(!checked) } } }) diff --git a/compose-multiplatform-material3/src/jsMain/kotlin/com/huanshankeji/compose/material3/ext/Card.js.kt b/compose-multiplatform-material3/src/jsMain/kotlin/com/huanshankeji/compose/material3/ext/Card.js.kt index 14f54cb3..a4d3526e 100644 --- a/compose-multiplatform-material3/src/jsMain/kotlin/com/huanshankeji/compose/material3/ext/Card.js.kt +++ b/compose-multiplatform-material3/src/jsMain/kotlin/com/huanshankeji/compose/material3/ext/Card.js.kt @@ -6,19 +6,19 @@ import com.huanshankeji.compose.html.material3.MdElevatedCard import com.huanshankeji.compose.html.material3.MdFilledCard import com.huanshankeji.compose.html.material3.MdOutlinedCard import com.huanshankeji.compose.ui.Modifier -import com.varabyte.kobweb.compose.ui.toAttrs +import com.huanshankeji.compose.ui.toAttrs @Composable actual fun Card(modifier: Modifier, content: @Composable () -> Unit) = @OptIn(MaterialWebLabsApi::class) - MdFilledCard(modifier.platformModifier.toAttrs()) { content() } + MdFilledCard(modifier.toAttrs()) { content() } @Composable actual fun ElevatedCard(modifier: Modifier, content: @Composable () -> Unit) = @OptIn(MaterialWebLabsApi::class) - MdElevatedCard(modifier.platformModifier.toAttrs()) { content() } + MdElevatedCard(modifier.toAttrs()) { content() } @Composable actual fun OutlinedCard(modifier: Modifier, content: @Composable () -> Unit) = @OptIn(MaterialWebLabsApi::class) - MdOutlinedCard(modifier.platformModifier.toAttrs()) { content() } + MdOutlinedCard(modifier.toAttrs()) { content() } diff --git a/compose-multiplatform-material3/src/jsMain/kotlin/com/huanshankeji/compose/material3/ext/TextField.js.kt b/compose-multiplatform-material3/src/jsMain/kotlin/com/huanshankeji/compose/material3/ext/TextField.js.kt index 6bb9cd81..971f815a 100644 --- a/compose-multiplatform-material3/src/jsMain/kotlin/com/huanshankeji/compose/material3/ext/TextField.js.kt +++ b/compose-multiplatform-material3/src/jsMain/kotlin/com/huanshankeji/compose/material3/ext/TextField.js.kt @@ -10,20 +10,20 @@ import com.huanshankeji.compose.html.material3.MdOutlinedTextField import com.huanshankeji.compose.html.material3.MdTextFieldScope import com.huanshankeji.compose.ui.Modifier import com.huanshankeji.compose.ui.PlatformModifier +import com.huanshankeji.compose.ui.toAttrs import com.huanshankeji.compose.ui.toCommonModifier import com.huanshankeji.compose.web.attributes.ext.onInput import com.huanshankeji.compose.web.attributes.isFalseOrNull import com.huanshankeji.compose.web.attributes.isTrueOrNull import com.huanshankeji.compose.web.dom.ext.value import com.varabyte.kobweb.compose.ui.attrsModifier -import com.varabyte.kobweb.compose.ui.toAttrs import org.jetbrains.compose.web.attributes.AttrsScope import org.w3c.dom.HTMLElement private fun Modifier.toTextFieldAttrs( onValueChange: (String) -> Unit, keyboardOptions: KeyboardOptions, keyboardActions: KeyboardActions, ): AttrsScope.() -> Unit = - platformModifier.toAttrs { + toAttrs { // see https://stackoverflow.com/questions/574941/best-way-to-track-onchange-as-you-type-in-input-type-text onInput { onValueChange(it.target.value) } diff --git a/compose-multiplatform-material3/src/jsMain/kotlin/com/huanshankeji/compose/material3/lazy/ext/List.js.kt b/compose-multiplatform-material3/src/jsMain/kotlin/com/huanshankeji/compose/material3/lazy/ext/List.js.kt index c102ae2d..e39b0b81 100644 --- a/compose-multiplatform-material3/src/jsMain/kotlin/com/huanshankeji/compose/material3/lazy/ext/List.js.kt +++ b/compose-multiplatform-material3/src/jsMain/kotlin/com/huanshankeji/compose/material3/lazy/ext/List.js.kt @@ -8,6 +8,7 @@ import com.huanshankeji.compose.html.material3.MdListScope import com.huanshankeji.compose.runtime.DeferredComposableRunner import com.huanshankeji.compose.ui.Modifier import com.huanshankeji.compose.ui.PlatformModifier +import com.huanshankeji.compose.ui.toAttrs import com.huanshankeji.compose.ui.toCommonModifier import com.varabyte.kobweb.compose.ui.attrsModifier import com.varabyte.kobweb.compose.ui.toAttrs @@ -39,7 +40,7 @@ actual class ListScope(val mdListScope: MdListScope) { @Composable private fun ListItem(content: ListItemComponents) = - mdListScope.MdListItem(attrs = content.contentModifier.platformModifier.toAttrs()) { + mdListScope.MdListItem(attrs = content.contentModifier.toAttrs()) { contentFromComponents(content) } From a7b76b7263c1b37693085cef92a57ad974b62fa4 Mon Sep 17 00:00:00 2001 From: Shreck Ye Date: Thu, 9 May 2024 17:50:30 +0800 Subject: [PATCH 71/75] Add the `NavigationBar` and `NavigationBarItem` composables and test them in the demo The corresponding commit: https://github.com/huanshankeji/compose-html-material/commit/414a42d87ab31d9fbc8fa6e58e4f01a8f134c85c --- .../ext/NavigationBar.androidxCommon.kt | 39 ++++++++++++++ .../compose/material3/ext/NavigationBar.kt | 47 ++++++++++++++++ .../compose/material3/ext/Text.kt | 6 +++ .../compose/material3/ext/NavigationBar.js.kt | 53 +++++++++++++++++++ .../compose/material/demo/Material3.kt | 16 ++++++ 5 files changed, 161 insertions(+) create mode 100644 compose-multiplatform-material3/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material3/ext/NavigationBar.androidxCommon.kt create mode 100644 compose-multiplatform-material3/src/commonMain/kotlin/com/huanshankeji/compose/material3/ext/NavigationBar.kt create mode 100644 compose-multiplatform-material3/src/jsMain/kotlin/com/huanshankeji/compose/material3/ext/NavigationBar.js.kt diff --git a/compose-multiplatform-material3/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material3/ext/NavigationBar.androidxCommon.kt b/compose-multiplatform-material3/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material3/ext/NavigationBar.androidxCommon.kt new file mode 100644 index 00000000..995b5c54 --- /dev/null +++ b/compose-multiplatform-material3/src/androidxCommonMain/kotlin/com/huanshankeji/compose/material3/ext/NavigationBar.androidxCommon.kt @@ -0,0 +1,39 @@ +package com.huanshankeji.compose.material3.ext + +import androidx.compose.material3.NavigationBarItem +import androidx.compose.runtime.Composable +import com.huanshankeji.compose.foundation.layout.PlatformRowScope +import com.huanshankeji.compose.toContentWithoutModifier +import com.huanshankeji.compose.ui.Modifier + +@Composable +actual fun NavigationBar( + modifier: Modifier, + content: @Composable NavigationBarScope.() -> Unit +) = + androidx.compose.material3.NavigationBar(modifier.platformModifier) { + NavigationBarScope(this).content() + } + +actual class NavigationBarScope(val rowScope: PlatformRowScope) + +@Composable +actual fun NavigationBarScope.NavigationBarItem( + selected: Boolean, + onClick: () -> Unit, + selectedIcon: @Composable (Modifier) -> Unit, + unselectedIcon: @Composable (Modifier) -> Unit, + modifier: Modifier, + enabled: Boolean, + label: String?, + alwaysShowLabel: Boolean +) = + rowScope.NavigationBarItem( + selected, + onClick, + (if (selected) selectedIcon else unselectedIcon).toContentWithoutModifier(), + modifier.platformModifier, + enabled, + label.toNullableInlineText(), + alwaysShowLabel + ) diff --git a/compose-multiplatform-material3/src/commonMain/kotlin/com/huanshankeji/compose/material3/ext/NavigationBar.kt b/compose-multiplatform-material3/src/commonMain/kotlin/com/huanshankeji/compose/material3/ext/NavigationBar.kt new file mode 100644 index 00000000..b87420e5 --- /dev/null +++ b/compose-multiplatform-material3/src/commonMain/kotlin/com/huanshankeji/compose/material3/ext/NavigationBar.kt @@ -0,0 +1,47 @@ +package com.huanshankeji.compose.material3.ext + +import androidx.compose.runtime.Composable +import com.huanshankeji.compose.material.icons.Icon +import com.huanshankeji.compose.ui.Modifier + +@Composable +expect fun NavigationBar( + modifier: Modifier = Modifier, + content: @Composable NavigationBarScope.() -> Unit +) + +expect class NavigationBarScope + +@Composable +expect fun NavigationBarScope.NavigationBarItem( + selected: Boolean, + onClick: () -> Unit, + selectedIcon: @Composable (Modifier) -> Unit, + unselectedIcon: @Composable (Modifier) -> Unit = selectedIcon, + modifier: Modifier = Modifier, + enabled: Boolean = true, + label: String? = null, + alwaysShowLabel: Boolean = true, +) + +@Composable +fun NavigationBarScope.NavigationBarItemWithMaterialIcons( + selected: Boolean, + onClick: () -> Unit, + selectedIcon: Icon, + unselectedIcon: Icon = selectedIcon, + modifier: Modifier = Modifier, + enabled: Boolean = true, + label: String? = null, + alwaysShowLabel: Boolean = true, +) = + NavigationBarItem( + selected, + onClick, + selectedIcon.toContentWithModifier(), + unselectedIcon.toContentWithModifier(), + modifier, + enabled, + label, + alwaysShowLabel + ) diff --git a/compose-multiplatform-material3/src/commonMain/kotlin/com/huanshankeji/compose/material3/ext/Text.kt b/compose-multiplatform-material3/src/commonMain/kotlin/com/huanshankeji/compose/material3/ext/Text.kt index 4d0c81d3..4d52d20a 100644 --- a/compose-multiplatform-material3/src/commonMain/kotlin/com/huanshankeji/compose/material3/ext/Text.kt +++ b/compose-multiplatform-material3/src/commonMain/kotlin/com/huanshankeji/compose/material3/ext/Text.kt @@ -24,3 +24,9 @@ fun String.toTextWithModifier(): @Composable (Modifier) -> Unit = fun String?.toNullableTextWithModifier(): @Composable ((Modifier) -> Unit)? = this?.toTextWithModifier() + +fun String.toInlineText(): @Composable () -> Unit = + { InlineText(this) } + +fun String?.toNullableInlineText(): @Composable (() -> Unit)? = + this?.toInlineText() diff --git a/compose-multiplatform-material3/src/jsMain/kotlin/com/huanshankeji/compose/material3/ext/NavigationBar.js.kt b/compose-multiplatform-material3/src/jsMain/kotlin/com/huanshankeji/compose/material3/ext/NavigationBar.js.kt new file mode 100644 index 00000000..957eef75 --- /dev/null +++ b/compose-multiplatform-material3/src/jsMain/kotlin/com/huanshankeji/compose/material3/ext/NavigationBar.js.kt @@ -0,0 +1,53 @@ +package com.huanshankeji.compose.material3.ext + +import androidx.compose.runtime.Composable +import com.huanshankeji.compose.html.material3.MaterialWebLabsApi +import com.huanshankeji.compose.html.material3.MdNavigationBar +import com.huanshankeji.compose.html.material3.MdNavigationTab +import com.huanshankeji.compose.html.material3.MdNavigationTabScope +import com.huanshankeji.compose.ui.Modifier +import com.huanshankeji.compose.ui.PlatformModifier +import com.huanshankeji.compose.ui.toAttrs +import com.huanshankeji.compose.ui.toCommonModifier +import com.huanshankeji.compose.web.attributes.isFalseOrNull +import com.huanshankeji.compose.web.attributes.isTrueOrNull +import com.varabyte.kobweb.compose.ui.attrsModifier +import org.jetbrains.compose.web.dom.ElementScope +import org.w3c.dom.HTMLElement + +@Composable +actual fun NavigationBar( + modifier: Modifier, + content: @Composable NavigationBarScope.() -> Unit +) = + @OptIn(MaterialWebLabsApi::class) + MdNavigationBar(attrs = modifier.toAttrs()) { + NavigationBarScope(this).content() + } + +actual class NavigationBarScope(val elementScope: ElementScope) + +@Composable +actual fun NavigationBarScope.NavigationBarItem( + selected: Boolean, + onClick: () -> Unit, + selectedIcon: @Composable (Modifier) -> Unit, + unselectedIcon: @Composable (Modifier) -> Unit, + modifier: Modifier, + enabled: Boolean, + label: String?, + alwaysShowLabel: Boolean +) = + @OptIn(MaterialWebLabsApi::class) + MdNavigationTab( + enabled.isFalseOrNull(), + selected.isTrueOrNull(), + alwaysShowLabel.isFalseOrNull(), + label, + attrs = modifier.toAttrs() + ) { + selectedIcon(PlatformModifier.attrsModifier { slot(MdNavigationTabScope.Slot.ActiveIcon) }.toCommonModifier()) + unselectedIcon( + PlatformModifier.attrsModifier { slot(MdNavigationTabScope.Slot.InactiveIcon) }.toCommonModifier() + ) + } diff --git a/demo/src/commonMain/kotlin/com/huanshankeji/compose/material/demo/Material3.kt b/demo/src/commonMain/kotlin/com/huanshankeji/compose/material/demo/Material3.kt index ffcc2d04..8d97f876 100644 --- a/demo/src/commonMain/kotlin/com/huanshankeji/compose/material/demo/Material3.kt +++ b/demo/src/commonMain/kotlin/com/huanshankeji/compose/material/demo/Material3.kt @@ -164,5 +164,21 @@ fun Material3(modifier: Modifier) { ElevatedCard { Text("elevated card", contentPaddingModifier) } OutlinedCard { Text("outlined card", contentPaddingModifier) } } + + var selectedIndex by remember { mutableStateOf(0) } + NavigationBar { + NavigationBarItemWithMaterialIcons( + selectedIndex == 0, + { selectedIndex = 0 }, + Icons.Default.Add, + label = "Add" + ) + NavigationBarItemWithMaterialIcons( + selectedIndex == 1, + { selectedIndex = 1 }, + Icons.Default.Remove, + label = "Remove" + ) + } } } From cc42bc3dfbd3b2a7e93854b32509a2119c187474 Mon Sep 17 00:00:00 2001 From: Shreck Ye Date: Fri, 10 May 2024 08:29:44 +0800 Subject: [PATCH 72/75] Update the version of the "Compose HTML Material" dependency to the stable version "0.3.0" --- buildSrc/src/main/kotlin/VersionsAndDependencies.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/buildSrc/src/main/kotlin/VersionsAndDependencies.kt b/buildSrc/src/main/kotlin/VersionsAndDependencies.kt index 2622872f..62f4d289 100644 --- a/buildSrc/src/main/kotlin/VersionsAndDependencies.kt +++ b/buildSrc/src/main/kotlin/VersionsAndDependencies.kt @@ -5,7 +5,7 @@ val projectVersion = "0.3.0-SNAPSHOT" object DependencyVersions { const val composeMultiplatform = ComposeBuildConfig.composeVersion // for "ui-unit" val kobweb = "0.17.3" - val huanshankejiComposeHtml = "0.3.0-SNAPSHOT" // TODO don't use a snapshot in a main branch + val huanshankejiComposeHtml = "0.3.0" val kmdc = "0.1.2" object Androidx { From 8306f71c3c74c7a776e00f21e4e06e0943176a53 Mon Sep 17 00:00:00 2001 From: Shreck Ye Date: Fri, 10 May 2024 11:18:51 +0800 Subject: [PATCH 73/75] Update README.md about the new components and recent API changes Components in one section are now ordered alphabetically. --- README.md | 61 ++++++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 47 insertions(+), 14 deletions(-) diff --git a/README.md b/README.md index ade5c67d..3d7358f2 100644 --- a/README.md +++ b/README.md @@ -17,7 +17,7 @@ This project is prototype and there is no documentation yet. Check out [the demo ### Components -#### Common (Foundation) components +#### Foundation components - `BasicText` @@ -30,35 +30,66 @@ This project is prototype and there is no documentation yet. Check out [the demo - `Box` - `Column` (via flexbox on web) - `Row` (via flexbox on web) +- `Spacer` -#### Material components +##### Lazy + +- `LazyColumn` +- `LazyRow` + +#### Material 2 components - `Button` - `Card` +- `Checkbox` +- `Divider` (not working properly on JS yet) - `Icon` - `IconButton` -- `LazyColumn`/`ScrollableList` (visually inconsistent for now) -- `Text`/`MaterialText` -- `TextField` -- `Checkbox` -- `Divider` (visually inconsistent for now) +- `Switch` +- `Text` ##### `ext` components - `Button` - `IconButton` +- `RadioRow`, `RadioGroupRow` +- `SwitchWithLabel` +- `MaterialText`, `InlineText` +- `TextField`, `OutlinedTextField` - `TopAppBarScaffold` -- `InlineText` -- `RadioRow` -- `RadioGroupRow` + +##### `lazy.ext` components + +- `List`/`LazyColumnList` (visually inconsistent for now) #### Material 3 components -- `Button` +- `Button` (`FilledButton`), `ElevatedButton`, `FilledTonalButton`, `OutlinedButton`, `TextButton` +- `Card` (`FilledCard`), `ElevatedCard`, `OutlinedCard` +- `Checkbox` +- `FloatingActionButton`, `SmallFloatingActionButton`, `LargeFloatingActionButton`, `ExtendedFloatingActionButton` +- `Icon` +- `IconButton`, `IconToggleButton`, `FilledIconButton`, `FilledIconToggleButton`, `FilledTonalIconButton`, `FilledTonalIconToggleButton`, `OutlinedIconButton`, `OutlinedIconToggleButton` +- `Switch` +- `Text` + +##### `ext` components + +- `Button` (`FilledButton`), `ElevatedButton`, `FilledTonalButton`, `OutlinedButton`, `TextButton` +- `Card` (`FilledCard`), `ElevatedCard`, `OutlinedCard` +- `FloatingActionButton`, `SmallFloatingActionButton`, `LargeFloatingActionButton`, `ExtendedFloatingActionButton` +- `IconButton`, `IconToggleButton`, `FilledIconButton`, `FilledIconToggleButton`, `FilledTonalIconButton`, `FilledTonalIconToggleButton`, `OutlinedIconButton`, `OutlinedIconToggleButton` +- `NavigationBar`, `NavigationBarItem` +- `MaterialText`, `InlineText` +- `TextField`, `OutlinedTextField` + +##### `lazy.ext` components + +- `List`/`LazyColumnList` (slightly visually inconsistent) -#### Components in the `ext` packages +#### About `ext` components (components in the `ext` packages) -The components in the `ext` packages don't follow the `androidx.compose` APIs exactly, but rather provide wrappers are idiomatic and conventional on both kinds of targets, wrapping different APIs which can't be unified following the `androidx.compose` APIs. +The components in the `ext` packages don't follow the `androidx.compose` APIs exactly, but rather provide wrappers are more idiomatic and conventional on both kinds of targets, wrapping different APIs which can't be unified following the `androidx.compose` APIs. ### Styles (obsolete in the legacy module, for removal) @@ -82,6 +113,8 @@ The functions in `StyleScope`: - `padding` - `background` - `border` (visually inconsistent) +- `onClick` +- `verticalScroll`, `horizontalScroll` (`ScrollState` not supported on JS yet) #### `ext` modifiers @@ -108,7 +141,7 @@ repositories { ### Material Symbols & Icons on JS -See [the corresponding section in Compose HTML Material]() for Material Icons on JS. +See [the corresponding section in Compose HTML Material](https://github.com/huanshankeji/compose-html-material?tab=readme-ov-file#material-symbols--icons) for Material Icons on JS. ## About Kobweb Silk From e4566ddaad8d4b13a2e848497d6baa0547032987 Mon Sep 17 00:00:00 2001 From: Shreck Ye Date: Fri, 10 May 2024 12:09:13 +0800 Subject: [PATCH 74/75] Update README.md throughly --- LEGACY_README.md | 18 ++++++++++++++ README.md | 61 ++++++++++++++++++++++++------------------------ 2 files changed, 49 insertions(+), 30 deletions(-) create mode 100644 LEGACY_README.md diff --git a/LEGACY_README.md b/LEGACY_README.md new file mode 100644 index 00000000..ba3722d8 --- /dev/null +++ b/LEGACY_README.md @@ -0,0 +1,18 @@ +# Legacy README + +This file contains information on legacy code which is not removed yet. + +## Supported features + +### Styles + +The `ModifierOrAttrsScope.styles` function and the `StyleScope` class provide a universal interface for `Modifier`s and CSS styles. + +The functions in `StyleScope`: + +- `height` +- `margin` +- `width` +- `backgroundColor` +- `platformBorder` +- `outerBorder` diff --git a/README.md b/README.md index 3d7358f2..611153e1 100644 --- a/README.md +++ b/README.md @@ -1,17 +1,15 @@ -# Compose Multiplatform common extensions and Material wrappers for `androidx.compose.material` and Compose HTML +# Compose Multiplatform Material: unified Compose Multiplatform common extensions and Material wrappers for `androidx.compose` and Compose HTML -[![Maven Central](https://img.shields.io/maven-central/v/com.huanshankeji/compose-multiplatform-material)](https://search.maven.org/search?q=g:com.huanshankeji%20AND%20a:compose-multiplatform-*) -![Kotlin version](https://kotlin-version.aws.icerock.dev/kotlin-version?group=com.huanshankeji&name=compose-multiplatform-material) +[![Maven Central](https://img.shields.io/maven-central/v/com.huanshankeji/compose-multiplatform-material3)](https://search.maven.org/search?q=g:com.huanshankeji%20AND%20a:compose-multiplatform-*) +![Kotlin version](https://kotlin-version.aws.icerock.dev/kotlin-version?group=com.huanshankeji&name=compose-multiplatform-material3) -Some simple unified Compose Multiplatform wrappers of common components, layouts, and Material Design components for `androidx.compose.material` (officially supported on Android, desktop (JVM), iOS, web (Kotlin/Wasm)) and Compose HTML (mainly based on [Kobweb Silk](https://github.com/varabyte/kobweb?tab=readme-ov-file#silk) [Compose](https://github.com/varabyte/kobweb/tree/main/frontend/kobweb-compose), [KMDC](https://github.com/mpetuska/kmdc), and [Compose HTML Material](https://github.com/huanshankeji/compose-html-material) (which is then based on [Material Web](https://github.com/material-components/material-web))) +Unified Compose Multiplatform wrappers of common components, layouts, and Material Design components for `androidx.compose` (officially supported on Android, desktop (JVM), iOS, and web (Kotlin/Wasm)) and Compose HTML (mainly based on [Kobweb Silk](https://github.com/varabyte/kobweb?tab=readme-ov-file#silk) [Compose](https://github.com/varabyte/kobweb/tree/main/frontend/kobweb-compose), [KMDC](https://github.com/mpetuska/kmdc), and [Compose HTML Material](https://github.com/huanshankeji/compose-html-material) (which is then based on [Material Web](https://github.com/material-components/material-web))) - +We try to provide a set of common extensions and composable component APIs akin to those in `androidx.compose` (`androidx.compose.foundation`, `androidx.compose.material`, and `androidx.compose.material3`), meanwhile making them compatible with the Compose HTML APIs. However, only subsets of the composables and composable parameters are supported due to the API differences, limitations of the JS (web) platform and the Compose HTML composables this project depends on, and our limited effort. -We try to make the function types of the composable components follow those in `androidx.compose.foundation` and `androidx.compose.material`, meanwhile being compatible with the Compose HTML APIs. However, only subsets of the composables and composable arguments are supported due to the API differences, limitations of the Compose HTML composables this project depends on, and our limited effort. +Complete visual consistency across different platforms is not guaranteed. -Visual consistency across different platforms is not guaranteed. - -This project is prototype and there is no documentation yet. Check out [the demo project](demo) on how to use the components. +This project is still in development and has not reached the stable state yet. Some APIs are likely to be changed and there is no detailed documentation yet. Check out [the demo project](demo) on how to use the components in addition to the information below. ## Supported features @@ -28,8 +26,8 @@ This project is prototype and there is no documentation yet. Check out [the demo ##### Layouts - `Box` -- `Column` (via flexbox on web) -- `Row` (via flexbox on web) +- `Column` (via flexbox on JS) +- `Row` (via flexbox on JS) - `Spacer` ##### Lazy @@ -91,25 +89,12 @@ This project is prototype and there is no documentation yet. Check out [the demo The components in the `ext` packages don't follow the `androidx.compose` APIs exactly, but rather provide wrappers are more idiomatic and conventional on both kinds of targets, wrapping different APIs which can't be unified following the `androidx.compose` APIs. -### Styles (obsolete in the legacy module, for removal) - -The `ModifierOrAttrsScope.styles` function and the `StyleScope` class provide a universal interface for `Modifier`s and CSS styles. - -The functions in `StyleScope`: - -- `height` -- `margin` -- `width` -- `backgroundColor` -- `platformBorder` -- `outerBorder` - ### Modifiers - size modifiers - - `size`, `sizeIn`, `fillMaxSize` - - `width`, `widthIn`, `fillMaxWidth` - - `height`, `heightIn`, `fillMaxHeight` + - `size`, `sizeIn`, `fillMaxSize` + - `width`, `widthIn`, `fillMaxWidth` + - `height`, `heightIn`, `fillMaxHeight` - `padding` - `background` - `border` (visually inconsistent) @@ -129,26 +114,42 @@ Maven coordinate: "com.huanshankeji:compose-multiplatform-$module:$version" ``` +For example, depend on the Material 3 module with Gradle: + +```kotlin +kotlin { + sourceSets { + commonMain { + dependencies { + // ... + implementation("com.huanshankeji:compose-multiplatform-material3:$version") + } + } + } +} +``` + View [all the artifacts on Maven Central](https://search.maven.org/search?q=g:com.huanshankeji%20AND%20a:compose-multiplatform-*). This project depends on [Kobweb](https://github.com/varabyte/kobweb) which is not published to Maven Central yet, so you have to add the following Maven repository: ```kotlin repositories { + mavenCentral() maven("https://us-central1-maven.pkg.dev/varabyte-repos/public") } ``` ### Material Symbols & Icons on JS -See [the corresponding section in Compose HTML Material](https://github.com/huanshankeji/compose-html-material?tab=readme-ov-file#material-symbols--icons) for Material Icons on JS. +See [the corresponding section in Compose HTML Material](https://github.com/huanshankeji/compose-html-material?tab=readme-ov-file#material-symbols--icons) for configuring Material Icons on JS. ## About Kobweb Silk The Kotlin/JS (Compose HTML) portion of this project depends on [Kobweb Compose](https://github.com/varabyte/kobweb/blob/main/frontend/kobweb-compose/README.md) of [Kobweb Silk](https://github.com/varabyte/kobweb?tab=readme-ov-file#silk) which is a UI layer built upon Compose HTML that provides `Modifier` (type-safe CSS API wrappers) and layout APIs. Here is a list of topics in their README.md that should be helpful when you use this library in Compose HTML, especially if you need to customize the components further on Kotlin/JS (Compose HTML): 1. [Silk](https://github.com/varabyte/kobweb?tab=readme-ov-file#silk) - 1. [Modifier](https://github.com/varabyte/kobweb?tab=readme-ov-file#modifier) - 1. [attrsModifier and styleModifier](https://github.com/varabyte/kobweb?tab=readme-ov-file#attrsmodifier-and-stylemodifier) + 1. [Modifier](https://github.com/varabyte/kobweb?tab=readme-ov-file#modifier) + 1. [attrsModifier and styleModifier](https://github.com/varabyte/kobweb?tab=readme-ov-file#attrsmodifier-and-stylemodifier) 1. [General purpose improvements on top of Compose HTML and Kotlin/JS](https://github.com/varabyte/kobweb?tab=readme-ov-file#general-purpose-improvements-on-top-of-compose-html-and-kotlinjs) 1. [What about Compose Multiplatform for Web?](https://github.com/varabyte/kobweb?tab=readme-ov-file#what-about-compose-multiplatform-for-web) From 3487e71606b07c757d1d063a48ca5f5d052b4e9c Mon Sep 17 00:00:00 2001 From: Shreck Ye Date: Fri, 10 May 2024 12:12:23 +0800 Subject: [PATCH 75/75] Put the version of "material-symbols" in `DependencyVersions` --- buildSrc/src/main/kotlin/VersionsAndDependencies.kt | 1 + demo/build.gradle.kts | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/buildSrc/src/main/kotlin/VersionsAndDependencies.kt b/buildSrc/src/main/kotlin/VersionsAndDependencies.kt index 62f4d289..191fc318 100644 --- a/buildSrc/src/main/kotlin/VersionsAndDependencies.kt +++ b/buildSrc/src/main/kotlin/VersionsAndDependencies.kt @@ -7,6 +7,7 @@ object DependencyVersions { val kobweb = "0.17.3" val huanshankejiComposeHtml = "0.3.0" val kmdc = "0.1.2" + val materialSymbols = "0.17.4" object Androidx { val activityCompose = "1.9.0" diff --git a/demo/build.gradle.kts b/demo/build.gradle.kts index 3b2d64a9..00f7929a 100644 --- a/demo/build.gradle.kts +++ b/demo/build.gradle.kts @@ -77,7 +77,7 @@ kotlin { jsMain { dependencies { implementation(compose.html.core) - implementation(npm("material-symbols", "0.17.4")) + implementation(npm("material-symbols", DependencyVersions.materialSymbols)) } } }