Skip to content

Instantly share code, notes, and snippets.

@ExNDY
Created May 15, 2024 16:40
Show Gist options
  • Save ExNDY/3acb7d506d5697437b8e9ad70a656650 to your computer and use it in GitHub Desktop.
Save ExNDY/3acb7d506d5697437b8e9ad70a656650 to your computer and use it in GitHub Desktop.
Expandable card stack Compose
@Composable
fun <T> ExpandableCardStack(
elements: List<T>,
contentHeight: Dp,
contentVerticalPadding: Dp,
contentHorizontalPadding: Dp,
content: @Composable (Modifier) -> Unit,
modifier: Modifier = Modifier,
cardCornerRadius: Dp = 16.dp,
) {
var isHide by remember {
mutableStateOf(true)
}
Box(
modifier = modifier
.fillMaxWidth()
.wrapContentHeight(),
contentAlignment = Alignment.TopCenter
) {
val maxElevation = remember(elements) {
elements.size * 2
}
elements.forEachIndexed { index, _ ->
val verticalPadding by animateDpAsState(
targetValue = when (isHide) {
true -> if (index == 1) {
8.dp
} else if (index >= 2) {
16.dp
} else 0.dp
false -> (index * (contentHeight.value + contentVerticalPadding.value)).dp
},
label = "verticalPadding"
)
val horizontalPadding: Dp by animateDpAsState(
targetValue = when (isHide) {
true -> if (index == 1) {
contentHorizontalPadding / 2
} else if (index >= 2) {
contentHorizontalPadding
} else 0.dp
false -> 0.dp
},
label = "horizontalPadding"
)
if (index == 1 && isHide) {
Box(
modifier = Modifier
.zIndex(maxElevation.toFloat() - (index * 2))
.padding(top = verticalPadding)
.padding(horizontal = horizontalPadding)
.clip(RoundedCornerShape(cardCornerRadius))
.fillMaxWidth()
.height(120.dp)
.background(Color(0xFF919193))
)
} else if (index == 2 && isHide) {
Box(
modifier = Modifier
.zIndex(maxElevation.toFloat() - (index * 2))
.padding(top = verticalPadding)
.padding(horizontal = horizontalPadding)
.clip(RoundedCornerShape(cardCornerRadius))
.fillMaxWidth()
.height(120.dp)
.background(Color(0xFF4f5052))
)
} else if (index > 2 && isHide) {
Unit
} else {
content(
Modifier
.zIndex(maxElevation.toFloat() - (index * 2))
.padding(top = verticalPadding)
.padding(horizontal = horizontalPadding),
)
}
}
//Clickable transparent cover for expand stack without open first element
if (isHide) {
Box(
modifier = Modifier
.zIndex(maxElevation.toFloat() + 2)
.clip(RoundedCornerShape(cardCornerRadius))
.fillMaxWidth()
.height(contentHeight)
.clickable(
onClick = {
isHide = !isHide
}
)
)
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment