compose-menu icon indicating copy to clipboard operation
compose-menu copied to clipboard

Height of Scrollbar's Thumb is not adjustable

Open Kietyo opened this issue 8 months ago • 6 comments

I found that if the lazy column has 36K text elements, the scrollbar's height becomes pretty small:

Image

Is there a way to adjust the height of the scrollbar?

Current impl:

    val lazyListState = rememberLazyListState()
    val scrollAreaLazyListState = rememberScrollAreaState(lazyListState)
    ScrollArea(scrollAreaLazyListState) {
        LazyColumn(state = lazyListState, modifier = Modifier.fillMaxSize()) {
            for (file in audioFiles) {
                item(file.uri) {
                    Row(
                        modifier = Modifier
                            .padding(3.dp)
                            .background(MaterialTheme.colorScheme.primaryContainer, RoundedCornerShape(10.dp))
                            .padding(6.dp)
                        ,
                        horizontalArrangement = Arrangement.SpaceBetween,
                        verticalAlignment = Alignment.CenterVertically
                    ) {
                        Text("${file.title}",
                            modifier = Modifier.weight(0.8f)
                        )
                        Text("${file.durationString}",
                            modifier = Modifier.weight(0.2f)
                                .padding(end = scrollbarWidth),
                            textAlign = TextAlign.End
                        )
                    }
                }

            }
        }

        VerticalScrollbar(
            modifier = Modifier.align(Alignment.TopEnd)
                .fillMaxHeight()
                .width(scrollbarWidth)
        ) {
            Thumb(
                modifier = Modifier.background(
                    Color.Black.copy(0.3f), RoundedCornerShape(100)
                ),
                enabled = true
            )
        }
    }

Kietyo avatar May 22 '25 04:05 Kietyo

I see that the minimum height of the scrollbar is provided here:

Image

Would it be possible to make it configurable?

Kietyo avatar May 22 '25 04:05 Kietyo

You should be able to do this by setting the height of the Thumb() (ie Modifier.height() or Modifier.heightIn())

Could you check that and let me know if that works? If not, then it is a bug

alexstyl avatar May 22 '25 16:05 alexstyl

Tried:

            VerticalScrollbar(
                modifier = Modifier
                    .align(Alignment.TopEnd)
                    .fillMaxHeight()
                    .width(scrollbarWidth)
            ) {
                Thumb(
                    modifier = Modifier
                        .height(50.dp)
                        .background(
                            Color.Black.copy(0.3f), RoundedCornerShape(100)
                        ),
                    enabled = true
                )
            }

Didn't work:

Image

Tried 2:

            VerticalScrollbar(
                modifier = Modifier
                    .align(Alignment.TopEnd)
                    .fillMaxHeight()
                    .width(scrollbarWidth)
            ) {
                Thumb(
                    modifier = Modifier
                        .background(
                            Color.Black.copy(0.3f), RoundedCornerShape(100)
                        )
                        .height(50.dp)
                    ,
                    enabled = true
                )
            }

Didn't work. Same as above.

Tried 3:

            VerticalScrollbar(
                modifier = Modifier
                    .align(Alignment.TopEnd)
                    .fillMaxHeight()
                    .width(scrollbarWidth)
            ) {
                Thumb(
                    modifier = Modifier
                        .heightIn(50.dp, 100.dp)
                        .background(
                            Color.Black.copy(0.3f), RoundedCornerShape(100)
                        )
                    ,
                    enabled = true
                )
            }

Didn't work.

Kietyo avatar May 28 '25 05:05 Kietyo

That's a bug then. Let me have a look and will let you know

alexstyl avatar May 28 '25 09:05 alexstyl

thx for taking a look!

Kietyo avatar May 29 '25 04:05 Kietyo

So I've found that any height you specify for the Thumb modifier is ignored (unless you use requiredHeight, more on that later). This is due to the following code giving fixed Constraints in ScrollArea's verticalMeasurePolicy, which is used for the Layout parent of the Thumb's Box where your Thumb function call's provided modifier is applied

    val placeable = measurables.firstOrNull()?.measure(
        Constraints.fixed(
            constraints.constrainWidth(scrollThickness), pixelRange.size
        )
    )

By allowing the consumer's modifier to affect the height, this effectively breaks the way the bar works because the scroll amounts are based on the height that the library calculates, not the actual height of the view itself. Accepting a minHeight parameter that could affect the minimumHeight part of code that @Kietyo found would be the quick fix since that code is already baked into the math. If you wanted a Thumb implementation that could work via the modifier (or even allow a user-provided thumb view), you'd have to take the measured height into account or adjust the scrollbarDrag modifier to account for the Thumb view's offset. The latter would be cool because it could enable you to make a thumb like the letter in the Contacts app, i.e., not a scrollbar per se but a fast-scroll handle (though getting the stops, if desired, would be a whole other ordeal).

In the meantime I've found setting the requiredHeight modifier on your Thumb component when you calculate that the bar's height is going to be too small, and then vertically-padding the VerticalScrollbar to shrink the range used for the aforementioned calculations has worked. I threw the components and modifiers in a gist along with the example, but I warn you it's pretty hacky

https://gist.github.com/beeks/22c0d21ade95f3f725b8c517792a3d2a

beeks avatar Jul 01 '25 23:07 beeks