Skip to content

Commit 1fe305a

Browse files
committed
Make the demos fit better in the screen with navigation, and add an imitateAndroidxLayout JS DOM modifier and replace sizeFitContent with it in the layouts
Resolve #29, resolve #38 Extract more common functions for the CSS `stretch` value BTW. There is a new UI issue that the scrollable padding is not at the right place.
1 parent 911a1aa commit 1fe305a

File tree

14 files changed

+126
-36
lines changed

14 files changed

+126
-36
lines changed

compose-multiplatform-common/src/commonMain/kotlin/com/huanshankeji/compose/foundation/Scroll.kt

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,9 @@ expect class ScrollState
1717
It seems `state` has to be achieved with `DisposableEffect` on JS which can not be set with the Kobweb `Modifier` yet.
1818
See https://developer.mozilla.org/en-US/docs/Web/API/Element/scrollTop.
1919
*/
20+
/**
21+
* Note that if the component is a layout, it applies to the target as a whole on `androidx` targets, but applies to its content on JS DOM.
22+
*/
2023
expect fun Modifier.verticalScroll(
2124
state: ScrollState
2225
/*
@@ -27,3 +30,8 @@ expect fun Modifier.verticalScroll(
2730
): Modifier
2831

2932
expect fun Modifier.horizontalScroll(state: ScrollState): Modifier
33+
34+
/*
35+
@Composable
36+
expect fun VerticalScrollBox(content : @Composable () ->Unit)
37+
*/

compose-multiplatform-common/src/jsMain/kotlin/com/huanshankeji/compose/foundation/layout/Box.js.kt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import androidx.compose.runtime.Stable
66
import com.huanshankeji.compose.ui.Alignment
77
import com.huanshankeji.compose.ui.Modifier
88
import com.huanshankeji.compose.ui.PlatformModifier
9-
import com.huanshankeji.kobweb.compose.ui.modifiers.sizeFitContent
9+
import com.huanshankeji.kobweb.compose.ui.modifiers.imitateAndroidxLayout
1010
import com.varabyte.kobweb.compose.foundation.layout.LayoutScopeMarker
1111
import com.varabyte.kobweb.compose.foundation.layout.Box as PlatformBox
1212
import com.varabyte.kobweb.compose.foundation.layout.BoxScope as PlatformBoxScope
@@ -19,14 +19,14 @@ actual fun Box(
1919
) {
2020
AddKobwebComposeStyleSheet()
2121
PlatformBox(
22-
PlatformModifier.sizeFitContent().then(modifier.platformModifier),
22+
PlatformModifier.imitateAndroidxLayout().then(modifier.platformModifier),
2323
contentAlignment.platformValue,
2424
) { BoxScope.Impl(this).content() }
2525
}
2626

2727
@Composable
2828
actual fun Box(modifier: Modifier) =
29-
PlatformBox(PlatformModifier.sizeFitContent().then(modifier.platformModifier))
29+
PlatformBox(PlatformModifier.imitateAndroidxLayout().then(modifier.platformModifier))
3030

3131
@LayoutScopeMarker
3232
@Immutable

compose-multiplatform-common/src/jsMain/kotlin/com/huanshankeji/compose/foundation/layout/Column.js.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import androidx.compose.runtime.Stable
66
import com.huanshankeji.compose.ui.Alignment
77
import com.huanshankeji.compose.ui.Modifier
88
import com.huanshankeji.compose.ui.PlatformModifier
9-
import com.huanshankeji.kobweb.compose.ui.modifiers.sizeFitContent
9+
import com.huanshankeji.kobweb.compose.ui.modifiers.imitateAndroidxLayout
1010
import com.varabyte.kobweb.compose.foundation.layout.LayoutScopeMarker
1111

1212
@Composable
@@ -19,7 +19,7 @@ actual fun Column(
1919
AddKobwebComposeStyleSheet()
2020
com.varabyte.kobweb.compose.foundation.layout.Column(
2121
PlatformModifier
22-
.sizeFitContent() // "fit-content" is added to make it consistent with the `androidx` one
22+
.imitateAndroidxLayout() // "fit-content" is added to make it consistent with the `androidx` one
2323
.stylesFrom(verticalArrangement)
2424
.then(modifier.platformModifier),
2525
verticalArrangement.platformValue,

compose-multiplatform-common/src/jsMain/kotlin/com/huanshankeji/compose/foundation/layout/Row.js.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import androidx.compose.runtime.Stable
66
import com.huanshankeji.compose.ui.Alignment
77
import com.huanshankeji.compose.ui.Modifier
88
import com.huanshankeji.compose.ui.PlatformModifier
9-
import com.huanshankeji.kobweb.compose.ui.modifiers.sizeFitContent
9+
import com.huanshankeji.kobweb.compose.ui.modifiers.imitateAndroidxLayout
1010
import com.varabyte.kobweb.compose.foundation.layout.LayoutScopeMarker
1111

1212
@Composable
@@ -19,7 +19,7 @@ actual fun Row(
1919
AddKobwebComposeStyleSheet()
2020
com.varabyte.kobweb.compose.foundation.layout.Row(
2121
PlatformModifier
22-
.sizeFitContent()
22+
.imitateAndroidxLayout()
2323
.stylesFrom(horizontalArrangement)
2424
.then(modifier.platformModifier),
2525
horizontalArrangement.platformValue,

compose-multiplatform-common/src/jsMain/kotlin/com/huanshankeji/compose/foundation/layout/ext/Size.js.kt

Lines changed: 23 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,28 +7,44 @@ import com.huanshankeji.compose.ui.Modifier
77
import com.huanshankeji.compose.web.css.height
88
import com.huanshankeji.compose.web.css.width
99
import com.varabyte.kobweb.compose.ui.styleModifier
10+
import org.jetbrains.compose.web.css.StyleScope
1011

1112
private const val CSS_STRETCH_VALUE = "stretch" // This does not work on Chrome.
12-
private val cssStretchValueBrowserDependent =
13+
private const val CSS_WEBKIT_STRETCH_VALUE = "-webkit-fill-available"
14+
private const val CSS_MOZ_STRETCH_VALUE = "-moz-available"
15+
val cssWidthStretchValueBrowserDependent =
1316
when (browser) {
14-
Browser.Webkit -> "-webkit-fill-available"
15-
Browser.Mozilla -> "-moz-available"
17+
Browser.Webkit -> CSS_WEBKIT_STRETCH_VALUE
18+
Browser.Mozilla -> CSS_MOZ_STRETCH_VALUE
1619
null -> ""
1720
}
1821

22+
val cssHeightStretchValueBrowserDependent =
23+
when (browser) {
24+
Browser.Webkit -> CSS_WEBKIT_STRETCH_VALUE
25+
Browser.Mozilla -> "100%" // Setting `CSS_MOZ_STRETCH_VALUE` for `height` seems to be not available on Firefox. See https://developer.mozilla.org/en-US/docs/Web/CSS/height#browser_compatibility.
26+
null -> ""
27+
}
28+
29+
fun StyleScope.widthStretch() =
30+
width(cssWidthStretchValueBrowserDependent)
31+
32+
fun StyleScope.heightStretch() =
33+
height(cssHeightStretchValueBrowserDependent)
34+
1935
@Stable
2036
actual fun Modifier.fillMaxWidthStretch(): Modifier =
21-
platformModify { styleModifier { width(cssStretchValueBrowserDependent) } }
37+
platformModify { styleModifier { widthStretch() } }
2238

2339
@Stable
2440
actual fun Modifier.fillMaxHeightStretch(): Modifier =
25-
platformModify { styleModifier { height(cssStretchValueBrowserDependent) } } // Setting this for `height` seems to be not available on Firefox. See https://developer.mozilla.org/en-US/docs/Web/CSS/height#browser_compatibility.
41+
platformModify { styleModifier { heightStretch() } }
2642

2743
@Stable
2844
actual fun Modifier.fillMaxSizeStretch(): Modifier =
2945
platformModify {
3046
styleModifier {
31-
width(cssStretchValueBrowserDependent)
32-
height(cssStretchValueBrowserDependent) // Setting this for `height` seems to be not available on Firefox. See https://developer.mozilla.org/en-US/docs/Web/CSS/height#browser_compatibility.
47+
widthStretch()
48+
heightStretch()
3349
}
3450
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
package com.huanshankeji.kobweb.compose.ui.modifiers
2+
3+
import com.huanshankeji.compose.foundation.layout.ext.cssHeightStretchValueBrowserDependent
4+
import com.huanshankeji.compose.foundation.layout.ext.cssWidthStretchValueBrowserDependent
5+
import com.varabyte.kobweb.compose.css.Height
6+
import com.varabyte.kobweb.compose.css.Width
7+
import com.varabyte.kobweb.compose.css.height
8+
import com.varabyte.kobweb.compose.css.width
9+
import com.varabyte.kobweb.compose.ui.Modifier
10+
import com.varabyte.kobweb.compose.ui.styleModifier
11+
import org.jetbrains.compose.web.css.maxHeight
12+
import org.jetbrains.compose.web.css.maxWidth
13+
14+
15+
/**
16+
* A modifier for layouts to make them more consistent with the `androidx.compose` behavior,
17+
* by adding the parent sizes as max constrains for the children.
18+
* Doing this prevents the children to push the parent out of the parent's parent,
19+
* and make the `overflow-*` CSS property / the `*Scroll` modifier work better on JS DOM.
20+
* See https://developer.android.com/develop/ui/compose/layouts/constraints-modifiers for more details.
21+
*/
22+
fun Modifier.imitateAndroidxLayout() =
23+
styleModifier {
24+
width(Width.FitContent)
25+
height(Height.FitContent)
26+
maxWidth(cssWidthStretchValueBrowserDependent)
27+
maxHeight(cssHeightStretchValueBrowserDependent)
28+
}

compose-multiplatform-common/src/jsMain/kotlin/com/huanshankeji/kobweb/compose/ui/modifiers/Size.kt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,5 +14,8 @@ fun Modifier.size(width: Width, height: Height): Modifier =
1414
}
1515

1616
//TODO consider removing and inlining this
17+
/**
18+
* Consider using [Modifier.imitateAndroidxLayout] instead when adding this for a layout.
19+
*/
1720
fun Modifier.sizeFitContent() =
1821
size(Width.FitContent, Height.FitContent)

compose-multiplatform-material2/src/jsMain/kotlin/com/huanshankeji/compose/material2/Card.js.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,10 @@ package com.huanshankeji.compose.material2
33
import androidx.compose.runtime.Composable
44
import com.huanshankeji.compose.ui.Modifier
55
import com.huanshankeji.compose.ui.PlatformModifier
6-
import com.huanshankeji.kobweb.compose.ui.modifiers.sizeFitContent
6+
import com.huanshankeji.kobweb.compose.ui.modifiers.imitateAndroidxLayout
77
import com.varabyte.kobweb.compose.ui.toAttrs
88
import dev.petuska.kmdc.card.MDCCard
99

1010
@Composable
1111
actual fun Card(modifier: Modifier, content: @Composable () -> Unit) =
12-
MDCCard(attrs = PlatformModifier.sizeFitContent().then(modifier.platformModifier).toAttrs()) { content() }
12+
MDCCard(attrs = PlatformModifier.imitateAndroidxLayout().then(modifier.platformModifier).toAttrs()) { content() }

demo/build.gradle.kts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ kotlin {
4848
implementation(compose.runtime)
4949
implementation(project(":compose-multiplatform-material2"))
5050
implementation(project(":compose-multiplatform-material3"))
51+
implementation(project(":compose-multiplatform-navigation"))
5152
/*
5253
see https://github.com/JetBrains/compose-multiplatform-core/blob/476d43b99a27696d12ef087e8028d90789645ba7/compose/ui/ui/build.gradle#L54
5354
and https://github.com/JetBrains/compose-multiplatform-core/blob/381796b5e682653aa1fa53e6bcf0441d06b873f8/compose/runtime/runtime/build.gradle#L124

demo/src/commonMain/kotlin/com/huanshankeji/compose/material/demo/App.kt

Lines changed: 34 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,14 @@ package com.huanshankeji.compose.material.demo
22

33
import androidx.compose.runtime.Composable
44
import androidx.compose.ui.unit.dp
5-
import com.huanshankeji.compose.foundation.layout.Box
6-
import com.huanshankeji.compose.foundation.layout.Row
7-
import com.huanshankeji.compose.foundation.layout.padding
8-
import com.huanshankeji.compose.foundation.rememberScrollState
9-
import com.huanshankeji.compose.foundation.verticalScroll
5+
import androidx.navigation.NavHostController
6+
import com.huanshankeji.androidx.navigation.compose.NavHost
7+
import com.huanshankeji.androidx.navigation.compose.composable
8+
import com.huanshankeji.androidx.navigation.compose.rememberNavController
9+
import com.huanshankeji.compose.foundation.layout.*
10+
import com.huanshankeji.compose.material3.Button
11+
import com.huanshankeji.compose.material3.ext.TaglessText
12+
import com.huanshankeji.compose.ui.Alignment
1013
import com.huanshankeji.compose.ui.Modifier
1114

1215
internal enum class Selection {
@@ -18,18 +21,35 @@ val listSize = 160.dp
1821
fun Modifier.contentPadding() = padding(16.dp)
1922
val contentPaddingModifier = Modifier.contentPadding()
2023

24+
enum class Screen {
25+
Home, Common, Material2, Material3
26+
}
27+
2128
@Composable
2229
fun App() {
23-
Row {
24-
@Composable
25-
fun subDemoModifier() =
26-
Modifier.weight(1f).verticalScroll(rememberScrollState())
30+
val navController = rememberNavController()
31+
NavHost(navController, Screen.Home.name) {
32+
composable(Screen.Home.name) { Home(navController) }
33+
//fun subDemoModifier()
34+
composable(Screen.Common.name) { Common() }
35+
composable(Screen.Material2.name) { Material2() }
36+
composable(Screen.Material3.name) { Material3() }
37+
}
38+
}
2739

28-
Common(subDemoModifier())
29-
// Putting the scroll modifier in the `Box` causes `java.lang.IllegalArgumentException: Can't represent a size of 2147483577 in Constraints`.
30-
Box(Modifier.weight(1f)) {
31-
Material2(Modifier.verticalScroll(rememberScrollState()))
40+
@Composable
41+
fun Home(navController: NavHostController) {
42+
Box(Modifier.fillMaxSize(), contentAlignment = Alignment.Center) {
43+
Column(verticalArrangement = Arrangement.spacedBy(16.dp)) {
44+
Button({ navController.navigate(Screen.Common.name) }) {
45+
TaglessText("Common")
46+
}
47+
Button({ navController.navigate(Screen.Material2.name) }) {
48+
TaglessText("Material 2")
49+
}
50+
Button({ navController.navigate(Screen.Material3.name) }) {
51+
TaglessText("Material 3")
52+
}
3253
}
33-
Material3(subDemoModifier())
3454
}
3555
}

0 commit comments

Comments
 (0)