Skip to content

Commit ad04477

Browse files
committed
Add the VerticalScrollBox and HorizontalScrollBox as alternatives to the *Scroll modifiers, update the demo with them to fix the issue of padding outside the scrollable part on JS DOM, and make some related improvements
Related improvements: 1. extract some common JS DOM composables `KobwebBox` and `DivBox` 1. fix the `ReplaceWith`s in `@Deprecated` annotations of the `padding` modifiers (introduced in commit 0cab51c) 1. update the default `NavHost` `contentAlignment` parameters to `TopStart` to match the `androidx` ones Using `Center` seems a mistake caused by a bad merge in `androidx.compose`. See https://github.com/JetBrains/compose-multiplatform-core/blame/c93b73c3924ddc12370f32ca504dafb29f497260/navigation/navigation-compose/src/commonMain/kotlin/androidx/navigation/compose/NavHost.kt#L149 for more info.
1 parent 0cab51c commit ad04477

File tree

11 files changed

+258
-122
lines changed

11 files changed

+258
-122
lines changed

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

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@ import androidx.compose.foundation.horizontalScroll
44
import androidx.compose.foundation.rememberScrollState
55
import androidx.compose.foundation.verticalScroll
66
import androidx.compose.runtime.Composable
7+
import com.huanshankeji.compose.foundation.layout.Box
8+
import com.huanshankeji.compose.foundation.layout.BoxScope
9+
import com.huanshankeji.compose.ui.Alignment
710
import com.huanshankeji.compose.ui.Modifier
811

912
@Composable
@@ -17,3 +20,21 @@ actual fun Modifier.verticalScroll(state: ScrollState): Modifier =
1720

1821
actual fun Modifier.horizontalScroll(state: ScrollState): Modifier =
1922
platformModify { horizontalScroll(state) }
23+
24+
@Composable
25+
actual fun VerticalScrollBox(
26+
boxModifier: Modifier,
27+
contentModifier: Modifier,
28+
contentAlignment: Alignment,
29+
content: @Composable BoxScope.() -> Unit
30+
) =
31+
Box(boxModifier.verticalScroll(rememberScrollState()).then(contentModifier), contentAlignment, content)
32+
33+
@Composable
34+
actual fun HorizontalScrollBox(
35+
boxModifier: Modifier,
36+
contentModifier: Modifier,
37+
contentAlignment: Alignment,
38+
content: @Composable BoxScope.() -> Unit
39+
) =
40+
Box(boxModifier.horizontalScroll(rememberScrollState()).then(contentModifier), contentAlignment, content)

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

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@ package com.huanshankeji.compose.foundation
22

33
import androidx.compose.runtime.Composable
44
import androidx.compose.runtime.Stable
5+
import com.huanshankeji.compose.foundation.layout.BoxScope
6+
import com.huanshankeji.compose.ui.Alignment
57
import com.huanshankeji.compose.ui.Modifier
68

79
@Composable
@@ -18,7 +20,9 @@ It seems `state` has to be achieved with `DisposableEffect` on JS which can not
1820
See https://developer.mozilla.org/en-US/docs/Web/API/Element/scrollTop.
1921
*/
2022
/**
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.
23+
* Note that if the component is a layout, for example a Material card,
24+
* it applies to the target as a whole on `androidx` targets, but applies to its content on JS DOM.
25+
* For consistency on different platforms, [VerticalScrollBox] is recommended over this modifier.
2226
*/
2327
expect fun Modifier.verticalScroll(
2428
state: ScrollState
@@ -29,9 +33,24 @@ expect fun Modifier.verticalScroll(
2933
*/
3034
): Modifier
3135

36+
/**
37+
* For consistency on different platforms, [HorizontalScrollBox] is recommended over this modifier.
38+
* @see verticalScroll
39+
*/
3240
expect fun Modifier.horizontalScroll(state: ScrollState): Modifier
3341

34-
/*
3542
@Composable
36-
expect fun VerticalScrollBox(content : @Composable () ->Unit)
37-
*/
43+
expect fun VerticalScrollBox(
44+
boxModifier: Modifier = Modifier,
45+
contentModifier: Modifier = Modifier,
46+
contentAlignment: Alignment = Alignment.TopStart,
47+
content: @Composable BoxScope.() -> Unit
48+
)
49+
50+
@Composable
51+
expect fun HorizontalScrollBox(
52+
boxModifier: Modifier = Modifier,
53+
contentModifier: Modifier = Modifier,
54+
contentAlignment: Alignment = Alignment.TopStart,
55+
content: @Composable BoxScope.() -> Unit
56+
)

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

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,19 +8,29 @@ import com.huanshankeji.compose.foundation.layout.ext.innerPadding
88
import com.huanshankeji.compose.foundation.layout.ext.outerPadding
99
import com.huanshankeji.compose.ui.Modifier
1010

11-
private const val PADDING_DEPRECATED_MESSAGE = "Use `paddingFirst` or checkout out `paddingLast` instead."
11+
private const val PADDING_DEPRECATED_MESSAGE = "Use `outerPadding` or checkout out `innerPadding` instead."
12+
13+
private const val REPLACE_WITH_PACKAGE = "com.huanshankeji.compose.foundation.layout.ext"
14+
private const val OUTER_PADDING_REPLACE_WITH_IMPORT = "$REPLACE_WITH_PACKAGE.outerPadding"
15+
private const val ABSOLUTE_OUTER_PADDING_REPLACE_WITH_IMPORT = "$REPLACE_WITH_PACKAGE.absoluteOuterPadding"
1216

1317
/**
1418
* See the KDoc of the overload with one [Dp] parameter for platform differences.
1519
*/
16-
@Deprecated(PADDING_DEPRECATED_MESSAGE, ReplaceWith("this.paddingFirst(start, top, end, bottom)"))
20+
@Deprecated(
21+
PADDING_DEPRECATED_MESSAGE,
22+
ReplaceWith("this.outerPadding(start, top, end, bottom)", OUTER_PADDING_REPLACE_WITH_IMPORT)
23+
)
1724
@Stable
1825
expect fun Modifier.padding(start: Dp = 0.dp, top: Dp = 0.dp, end: Dp = 0.dp, bottom: Dp = 0.dp): Modifier
1926

2027
/**
2128
* See the KDoc of the overload with one [Dp] parameter for platform differences.
2229
*/
23-
@Deprecated(PADDING_DEPRECATED_MESSAGE, ReplaceWith("this.paddingFirst(horizontal, vertical)"))
30+
@Deprecated(
31+
PADDING_DEPRECATED_MESSAGE,
32+
ReplaceWith("this.outerPadding(horizontal, vertical)", OUTER_PADDING_REPLACE_WITH_IMPORT)
33+
)
2434
@Stable
2535
expect fun Modifier.padding(horizontal: Dp = 0.dp, vertical: Dp = 0.dp): Modifier
2636

@@ -31,21 +41,27 @@ expect fun Modifier.padding(horizontal: Dp = 0.dp, vertical: Dp = 0.dp): Modifie
3141
* @see outerPadding
3242
* @see innerPadding
3343
*/
34-
@Deprecated(PADDING_DEPRECATED_MESSAGE, ReplaceWith("this.paddingFirst(all)"))
44+
@Deprecated(PADDING_DEPRECATED_MESSAGE, ReplaceWith("this.outerPadding(all)", OUTER_PADDING_REPLACE_WITH_IMPORT))
3545
@Stable
3646
expect fun Modifier.padding(all: Dp): Modifier
3747

3848
/**
3949
* See the KDoc of the overload with one [Dp] parameter for platform differences.
4050
*/
41-
@Deprecated(PADDING_DEPRECATED_MESSAGE, ReplaceWith("this.paddingFirst(paddingValues)"))
51+
@Deprecated(
52+
PADDING_DEPRECATED_MESSAGE,
53+
ReplaceWith("this.outerPadding(paddingValues)", OUTER_PADDING_REPLACE_WITH_IMPORT)
54+
)
4255
@Stable
4356
expect fun Modifier.padding(paddingValues: PaddingValues): Modifier
4457

4558
/**
4659
* See the KDoc of the overload with one [Dp] parameter for platform differences.
4760
*/
48-
@Deprecated(PADDING_DEPRECATED_MESSAGE, ReplaceWith("this.absolutePaddingFirst(left, top, right, bottom)"))
61+
@Deprecated(
62+
PADDING_DEPRECATED_MESSAGE,
63+
ReplaceWith("this.absoluteOuterPadding(left, top, right, bottom)", ABSOLUTE_OUTER_PADDING_REPLACE_WITH_IMPORT)
64+
)
4965
@Stable
5066
expect fun Modifier.absolutePadding(left: Dp = 0.dp, top: Dp = 0.dp, right: Dp = 0.dp, bottom: Dp = 0.dp): Modifier
5167

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

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,10 @@ import androidx.compose.runtime.Composable
44
import androidx.compose.runtime.Stable
55
import com.huanshankeji.compose.foundation.ext.css.horizontalScroll
66
import com.huanshankeji.compose.foundation.ext.css.verticalScroll
7+
import com.huanshankeji.compose.foundation.layout.Box
8+
import com.huanshankeji.compose.foundation.layout.BoxScope
9+
import com.huanshankeji.compose.foundation.layout.ext.KobwebBox
10+
import com.huanshankeji.compose.ui.Alignment
711
import com.huanshankeji.compose.ui.Modifier
812
import com.huanshankeji.compose.ui.PlatformModifier
913
import com.varabyte.kobweb.compose.ui.styleModifier
@@ -32,3 +36,24 @@ actual fun Modifier.verticalScroll(state: ScrollState): Modifier =
3236
actual fun Modifier.horizontalScroll(state: ScrollState): Modifier =
3337
platformModify { horizontalScroll() }
3438

39+
@Composable
40+
actual fun VerticalScrollBox(
41+
boxModifier: Modifier,
42+
contentModifier: Modifier,
43+
contentAlignment: Alignment,
44+
content: @Composable BoxScope.() -> Unit
45+
) =
46+
Box(boxModifier.verticalScroll(rememberScrollState())) {
47+
KobwebBox(contentModifier, contentAlignment, content)
48+
}
49+
50+
@Composable
51+
actual fun HorizontalScrollBox(
52+
boxModifier: Modifier,
53+
contentModifier: Modifier,
54+
contentAlignment: Alignment,
55+
content: @Composable BoxScope.() -> Unit
56+
) =
57+
Box(boxModifier.horizontalScroll(rememberScrollState())) {
58+
KobwebBox(contentModifier, contentAlignment, content)
59+
}

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

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,30 +3,30 @@ package com.huanshankeji.compose.foundation.layout
33
import androidx.compose.runtime.Composable
44
import androidx.compose.runtime.Immutable
55
import androidx.compose.runtime.Stable
6+
import com.huanshankeji.compose.foundation.layout.ext.KobwebBox
67
import com.huanshankeji.compose.ui.Alignment
78
import com.huanshankeji.compose.ui.Modifier
89
import com.huanshankeji.compose.ui.PlatformModifier
10+
import com.huanshankeji.compose.ui.toCommonModifier
911
import com.huanshankeji.kobweb.compose.ui.modifiers.imitateAndroidxLayout
1012
import com.varabyte.kobweb.compose.foundation.layout.LayoutScopeMarker
11-
import com.varabyte.kobweb.compose.foundation.layout.Box as PlatformBox
1213
import com.varabyte.kobweb.compose.foundation.layout.BoxScope as PlatformBoxScope
1314

1415
@Composable
1516
actual fun Box(
1617
modifier: Modifier,
1718
contentAlignment: Alignment,
1819
content: @Composable BoxScope.() -> Unit
19-
) {
20-
AddKobwebComposeStyleSheet()
21-
PlatformBox(
22-
PlatformModifier.imitateAndroidxLayout().then(modifier.platformModifier),
23-
contentAlignment.platformValue,
24-
) { BoxScope.Impl(this).content() }
25-
}
20+
) =
21+
KobwebBox(
22+
PlatformModifier.imitateAndroidxLayout().toCommonModifier().then(modifier),
23+
contentAlignment,
24+
content
25+
)
2626

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

3131
@LayoutScopeMarker
3232
@Immutable
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
package com.huanshankeji.compose.foundation.layout.ext
2+
3+
import androidx.compose.runtime.Composable
4+
import com.huanshankeji.compose.foundation.layout.AddKobwebComposeStyleSheet
5+
import com.huanshankeji.compose.foundation.layout.BoxScope
6+
import com.huanshankeji.compose.ui.CommonModifier
7+
import com.huanshankeji.compose.ui.PlatformModifier
8+
import com.huanshankeji.kobweb.compose.ui.modifiers.imitateAndroidxLayout
9+
import com.varabyte.kobweb.compose.dom.ElementRefScope
10+
import com.varabyte.kobweb.compose.foundation.layout.Box
11+
import com.varabyte.kobweb.compose.ui.toAttrs
12+
import org.jetbrains.compose.web.dom.ContentBuilder
13+
import org.jetbrains.compose.web.dom.Div
14+
import org.w3c.dom.HTMLDivElement
15+
import org.w3c.dom.HTMLElement
16+
import com.huanshankeji.compose.foundation.layout.BoxScope as CommonBoxScope
17+
import com.huanshankeji.compose.ui.Alignment as CommonAlignment
18+
import com.varabyte.kobweb.compose.foundation.layout.BoxScope as PlatformBoxScope
19+
import com.varabyte.kobweb.compose.ui.Alignment as PlatformAlignment
20+
21+
/**
22+
* Delegates to [Box] without [com.varabyte.kobweb.compose.ui.Modifier.imitateAndroidxLayout].
23+
*/
24+
@Composable
25+
fun KobwebBox(
26+
modifier: PlatformModifier = PlatformModifier,
27+
contentAlignment: PlatformAlignment = PlatformAlignment.TopStart,
28+
ref: ElementRefScope<HTMLElement>? = null,
29+
content: @Composable PlatformBoxScope.() -> Unit = {}
30+
) {
31+
AddKobwebComposeStyleSheet()
32+
Box(modifier, contentAlignment, ref, content)
33+
}
34+
35+
@Composable
36+
fun KobwebBox(
37+
modifier: CommonModifier = CommonModifier,
38+
contentAlignment: CommonAlignment,
39+
content: @Composable CommonBoxScope.() -> Unit = {}
40+
) =
41+
KobwebBox(modifier.platformModifier, contentAlignment.platformValue) {
42+
BoxScope.Impl(this).content()
43+
}
44+
45+
/**
46+
* Delegates to [Div] without [com.varabyte.kobweb.compose.ui.Modifier.imitateAndroidxLayout].
47+
*/
48+
@Composable
49+
fun DivBox(
50+
modifier: PlatformModifier = PlatformModifier,
51+
content: ContentBuilder<HTMLDivElement>? = null
52+
) =
53+
Div(modifier.toAttrs(), content)

compose-multiplatform-navigation/src/commonMain/kotlin/com/huanshankeji/androidx/navigation/compose/NavHost.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ expect fun NavHost(
1212
navController: NavHostController,
1313
startDestination: String,
1414
modifier: Modifier = Modifier,
15-
contentAlignment: Alignment = Alignment.Center,
15+
contentAlignment: Alignment = Alignment.TopStart,
1616
route: String? = null,
1717
builder: NavGraphBuilder.() -> Unit
1818
)
@@ -22,5 +22,5 @@ expect fun NavHost(
2222
navController: NavHostController,
2323
graph: NavGraph,
2424
modifier: Modifier = Modifier,
25-
contentAlignment: Alignment = Alignment.Center,
25+
contentAlignment: Alignment = Alignment.TopStart,
2626
)

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

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,12 @@ import androidx.navigation.NavHostController
66
import com.huanshankeji.androidx.navigation.compose.NavHost
77
import com.huanshankeji.androidx.navigation.compose.composable
88
import com.huanshankeji.androidx.navigation.compose.rememberNavController
9-
import com.huanshankeji.compose.foundation.layout.*
9+
import com.huanshankeji.compose.foundation.layout.Arrangement
10+
import com.huanshankeji.compose.foundation.layout.Box
11+
import com.huanshankeji.compose.foundation.layout.Column
12+
import com.huanshankeji.compose.foundation.layout.ext.fillMaxSizeStretch
13+
import com.huanshankeji.compose.foundation.layout.ext.innerPadding
14+
import com.huanshankeji.compose.foundation.layout.ext.outerPadding
1015
import com.huanshankeji.compose.material3.Button
1116
import com.huanshankeji.compose.material3.ext.TaglessText
1217
import com.huanshankeji.compose.ui.Alignment
@@ -18,8 +23,9 @@ internal enum class Selection {
1823

1924
val listSize = 160.dp
2025

21-
fun Modifier.contentPadding() = padding(16.dp)
22-
val contentPaddingModifier = Modifier.contentPadding()
26+
fun Modifier.outerContentPadding() = outerPadding(16.dp)
27+
fun Modifier.innerContentPadding() = innerPadding(16.dp)
28+
val contentPaddingModifier = Modifier.outerContentPadding()
2329

2430
enum class Screen {
2531
Home, Common, Material2, Material3
@@ -39,7 +45,7 @@ fun App() {
3945

4046
@Composable
4147
fun Home(navController: NavHostController) {
42-
Box(Modifier.fillMaxSize(), contentAlignment = Alignment.Center) {
48+
Box(Modifier.fillMaxSizeStretch(), contentAlignment = Alignment.Center) {
4349
Column(verticalArrangement = Arrangement.spacedBy(16.dp)) {
4450
Button({ navController.navigate(Screen.Common.name) }) {
4551
TaglessText("Common")

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

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ import com.huanshankeji.compose.foundation.ext.outerBorder
77
import com.huanshankeji.compose.foundation.ext.roundedCornerBackgroundAndOuterBorder
88
import com.huanshankeji.compose.foundation.ext.roundedCornerOuterBorder
99
import com.huanshankeji.compose.foundation.layout.*
10-
import com.huanshankeji.compose.foundation.layout.ext.fillMaxWidthStretch
1110
import com.huanshankeji.compose.foundation.lazy.LazyColumn
1211
import com.huanshankeji.compose.foundation.lazy.LazyListScope
1312
import com.huanshankeji.compose.foundation.lazy.LazyRow
@@ -17,9 +16,9 @@ import com.huanshankeji.compose.ui.Modifier
1716
import com.huanshankeji.compose.ui.graphics.Color
1817

1918
@Composable
20-
fun Common(modifier: Modifier = Modifier) {
19+
fun Common(/*modifier: Modifier = Modifier*/) {
2120
Column(
22-
modifier.fillMaxWidthStretch().verticalScroll(rememberScrollState()).contentPadding(),
21+
Modifier.verticalScroll(rememberScrollState()).innerContentPadding(),
2322
Arrangement.spacedBy(16.dp)
2423
) {
2524
BasicText("basic text 1")

0 commit comments

Comments
 (0)