Hi, I'm Trying to make a Composable that can expan...
# compose-desktop
l
Hi, I'm Trying to make a Composable that can expand and collapse with smooth animations. The code I managed to write closest to what I want is the following:
Copy code
@Composable
fun ExpandableLabeledBox (
    modifier: Modifier = Modifier,
    expanded: Boolean = true,
    onExpandedChanged: (Boolean) -> Unit,
    label: @Composable (RowScope.() -> Unit)? = null,
    content: @Composable ()->Unit
) {
    val icon = if (expanded) Icons.Default.ExpandLess else Icons.Default.ExpandMore
    val color = MaterialTheme.colors.primary
    val clipShape = RoundedCornerShape(5.dp)

    // The line to change
    val topSurfaceHeight by animateDpAsState(if (expanded) 180.dp else 35.dp)

    Surface(
        modifier = modifier
            .clip(clipShape)
            .border(1.dp, color, clipShape)
            .height(topSurfaceHeight)
    ) {
        Column(modifier = Modifier.fillMaxWidth()) {
            // Label
            Surface(
                modifier = Modifier
                    .clickable(onClick = { onExpandedChanged(!expanded) }),
                color = color
            ) {
                Row(
                    modifier = Modifier
                        .fillMaxWidth()
                        .height(IntrinsicSize.Min)
                        .padding(5.dp),
                    verticalAlignment = Alignment.CenterVertically,
                    horizontalArrangement = Arrangement.spacedBy(5.dp, Alignment.Start),
                )
                {
                    Icon(icon, null)
                    label?.invoke(this)
                }
            }

            // Content
            Box(modifier = Modifier.padding(10.dp)) {
                content()
            }
        }
    }
}
As you can see, I'm stuck with the animated size. 35.dp should be the height of the label 180.dp should be the height of the label + the height of the content. Also, perhaps my approach of cliping all content into a surface is bad.... How will you achieve that?
i
Isn't it just about something like
AnimatedVisibility
? As far as I remember our template has effect like you described
l
It was! So much simple thanks, code looks like:
Copy code
fun ExpandableLabeledBox (
    modifier: Modifier = Modifier,
    expanded: Boolean = true,
    onExpandedChanged: (Boolean) -> Unit,
    label: @Composable (RowScope.() -> Unit)? = null,
    content: @Composable ()->Unit
) {
    val icon = if (expanded) Icons.Default.ExpandLess else Icons.Default.ExpandMore
    val color = MaterialTheme.colors.primary
    val clipShape = RoundedCornerShape(5.dp)

    Column(
        modifier = modifier
            .clip(clipShape)
            .border(1.dp, color, clipShape)
            .fillMaxWidth()
    ) {
        // Label
        Surface(
            modifier = Modifier
                .clickable(onClick = { onExpandedChanged(!expanded) }),
            color = color
        ) {
            Row(
                modifier = Modifier
                    .fillMaxWidth()
                    .height(IntrinsicSize.Min)
                    .padding(5.dp),
                verticalAlignment = Alignment.CenterVertically,
                horizontalArrangement = Arrangement.spacedBy(5.dp, Alignment.Start),
            )
            {
                Icon(icon, null)
                label?.invoke(this)
            }
        }

        AnimatedVisibility(expanded) {
            // Content
            Box(modifier = Modifier.padding(10.dp)) {
                content()
            }
        }
    }
}