Skip to content

Commit fb269bd

Browse files
committed
Fix or try fixing JS DOM display issues in BoxWithConstraints, com.huanshankeji.compose.material2.ext.TopAppBarScaffold, and com.huanshankeji.compose.material3.lazy.ext.List
1. fix the bug that a direct child with `fillMaxSizeStretch` (CSS `stretch`) doesn't work properly in the `content` of `TopAppBarScaffold` that it's sometimes rendered with the height 0 This can be triggered either when used with `BoxWithConstraints` or by changing the window size, and the expected correct behavior can be restored by inspecting the element. The 0-height issue in `BoxWithConstraints` turns out to be caused by this. The root cause for this is that `fillMaxSizeStretch`/`stretch` seems buggy when used directly in a `position: absolute` parent. This may be a bug in the browser engines used. Consider reporting this. 1. try fixing an issue that a scrollable `List` with many items take all the space of a parent `Column` and hide components in the same `Column` before it, but fail
1 parent 171dd5b commit fb269bd

File tree

6 files changed

+41
-18
lines changed

6 files changed

+41
-18
lines changed

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

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

33
import androidx.compose.runtime.Composable
44
import androidx.compose.runtime.Stable
5+
import com.huanshankeji.compose.ExperimentalApi
56
import com.huanshankeji.compose.foundation.layout.BoxScope
67
import com.huanshankeji.compose.ui.Alignment
78
import com.huanshankeji.compose.ui.Modifier
@@ -24,6 +25,7 @@ See https://developer.mozilla.org/en-US/docs/Web/API/Element/scrollTop.
2425
* it applies to the target as a whole on `androidx` targets, but applies to its content on JS DOM.
2526
* For consistency on different platforms, [VerticalScrollBox] is recommended over this modifier.
2627
*/
28+
@ExperimentalApi
2729
expect fun Modifier.verticalScroll(
2830
state: ScrollState
2931
/*
@@ -37,6 +39,7 @@ expect fun Modifier.verticalScroll(
3739
* For consistency on different platforms, [HorizontalScrollBox] is recommended over this modifier.
3840
* @see verticalScroll
3941
*/
42+
@ExperimentalApi
4043
expect fun Modifier.horizontalScroll(state: ScrollState): Modifier
4144

4245
@Composable

common/src/commonMain/kotlin/com/huanshankeji/compose/ui/unit/ext/DpOrPercentage.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
package com.huanshankeji.compose.ui.unit.ext
22

33
import androidx.annotation.IntRange
4+
import com.huanshankeji.compose.ExperimentalApi
45

56
// not used yet
7+
@ExperimentalApi
68
sealed class DpOrPercentage {
79
class Dp(val dp: androidx.compose.ui.unit.Dp) : DpOrPercentage()
810
class Percentage(@IntRange(0, 100) val percentage: Int) : DpOrPercentage()

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

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,6 @@ actual object ScrollState
3434
actual fun Modifier.verticalScroll(state: ScrollState): Modifier =
3535
platformModify { verticalScroll() }
3636

37-
3837
actual fun Modifier.horizontalScroll(state: ScrollState): Modifier =
3938
platformModify { horizontalScroll() }
4039

common/src/jsMain/kotlin/com/huanshankeji/compose/foundation/layout/ext/BoxWithConstraints.js.kt

Lines changed: 18 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -18,36 +18,30 @@ actual fun BoxWithConstraints(
1818
contentAlignment: Alignment,
1919
content: @Composable BoxWithConstraintsScope.() -> Unit
2020
) {
21+
// `DpClientSize.unspecified` instead of null can be used by default to prevent the content from not rendering when `clientSize` is not set
2122
var clientSize by remember { mutableStateOf<ClientSize?>(null) }
2223
// `DivBox` doesn't work here either, so it should not be Kobweb's problem.
2324
Box(
2425
Modifier.fillMaxSizeStretch()
2526
.platformModify {
2627
attrsModifier {
2728
ref {
28-
//clientSize = ClientSize(it.clientWidth, it.clientHeight) // Adding this doesn't make a difference to solve the issue below.
29+
//console.log("Initial client size: ${it.clientWidth}, ${it.clientHeight}")
30+
// Adding this doesn't make a difference in solving the issue below.
31+
//clientSize = ClientSize(it.clientWidth, it.clientHeight)
2932
val resizeObserver = ResizeObserver { entries, _ ->
30-
val element = entries.first().target
33+
val element = entries.single().target
3134

3235
/*
3336
console.log("width: ${element.clientWidth}, height: ${element.clientHeight}")
3437
console.log(entries.first().contentBoxSize.first())
3538
console.log(entries.first().borderBoxSize.first())
36-
console.log(entries.first().devicePixelContentBoxSize.first())
39+
console.log(entries.first().devicePixelContentBoxSize.first()) // If there is zoom this one is different from the 2 above.
3740
*/
3841

39-
/* FIXME The height is sometimes 0 when resizing,
40-
a non-zero size (as filtered through below) is not observed in time,
41-
and sometimes a child element doesn't show,
42-
until it's inspected with the Chrome Dev Tools.
43-
I don't know whether this is a browser bug or a bug in our implementation.
44-
Therefore, the 0 size changes are filtered out.
45-
Uncomment the commented `console.log` debug code above to debug this further. */
4642
with(element) {
47-
if (clientWidth != 0 && clientHeight != 0) {
48-
//console.log("width: ${element.clientWidth}, height: ${element.clientHeight}")
49-
clientSize = ClientSize(clientWidth, clientHeight)
50-
}
43+
//console.log("width: $clientWidth, height: $clientHeight")
44+
clientSize = ClientSize(clientWidth, clientHeight)
5145
}
5246
}
5347
resizeObserver.observe(it)
@@ -78,3 +72,13 @@ class BoxWithConstraintsScopeImpl(
7872
) : BoxWithConstraintsScope
7973

8074
private class ClientSize(val clientWidth: Int, val clientHeight: Int)
75+
76+
// removed if not used
77+
/**
78+
* Made in [Dp] so [Dp.Unspecified] can be used.
79+
*/
80+
private class DpClientSize(val clientWidth: Dp, val clientHeight: Dp) {
81+
companion object {
82+
val unspecified = DpClientSize(Dp.Unspecified, Dp.Unspecified)
83+
}
84+
}

material2/src/jsMain/kotlin/com/huanshankeji/compose/material2/ext/TopAppBarScaffold.js.kt

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,8 @@ actual fun TopAppBarScaffold(
121121
actions,
122122
Modifier.weight(1f).fillMaxWidthStretch()
123123
) {
124+
// This part has a lot of nested `Div`s but works. Do not change unless you are sure that expected behavior is not broken.
125+
124126
// The content gets hidden behind the top app bar if this div is not added.
125127
Div({
126128
style {
@@ -134,9 +136,16 @@ actual fun TopAppBarScaffold(
134136
//overflow(Overflow.Auto) // This seems not needed. TODO remove if confirmed to be not needed
135137
}
136138
}) {
137-
// see `ScaffoldLayoutWithMeasureFix`
138-
val innerPadding = PaddingValues()
139-
content(innerPadding)
139+
// This nested `Div` is here so that a child using `fillMaxSizeStretch` works properly. `fillMaxSizeStretch` seems buggy when used directly in the `position: absolute` parent.
140+
Div({
141+
style {
142+
height(100.percent)
143+
}
144+
}) {
145+
// see `ScaffoldLayoutWithMeasureFix`
146+
val innerPadding = PaddingValues()
147+
content(innerPadding)
148+
}
140149
}
141150

142151
floatingActionButton?.let { fabWithPosition(it) }

material3/src/jsMain/kotlin/com/huanshankeji/compose/material3/lazy/ext/List.js.kt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,12 @@ actual class ListScope(val mdListScope: MdListScope) {
9090

9191
actual class ItemScope(val mdListItemScope: MdListItemScope)
9292

93+
/*
94+
@Composable
95+
fun PrimitiveList() =
96+
TODO() as Unit
97+
*/
98+
9399
@Composable
94100
actual fun List(
95101
modifier: Modifier,

0 commit comments

Comments
 (0)