commonMain.io.github.lyxnx.compose.pine.Card.kt Maven / Gradle / Ivy
package io.github.lyxnx.compose.pine
import androidx.compose.foundation.LocalIndication
import androidx.compose.foundation.background
import androidx.compose.foundation.border
import androidx.compose.foundation.clickable
import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.ColumnScope
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.shape.CornerBasedShape
import androidx.compose.material3.LocalContentColor
import androidx.compose.runtime.Composable
import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.runtime.getValue
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.isSpecified
import androidx.compose.ui.semantics.isTraversalGroup
import androidx.compose.ui.semantics.semantics
import androidx.compose.ui.unit.dp
import io.github.lyxnx.compose.ui.DropShadow
import io.github.lyxnx.compose.ui.dropShadow
import io.github.lyxnx.compose.ui.ifTrue
/**
* A Pine Theme card component
*
* @param modifier modifier to apply to this card
* @param onClick an optional click handler for when this card is clicked
* @param enabled whether this card is enabled - this will affect whether [onClick] is called
* @param interactionSource mutable interaction source to emit interaction events to
* @param shape the shape of this card
* @param colors colors to apply to this card
* @param shadowStyle the style of this card's shadow
* @param contentPadding padding to apply to the card content
* @param content actual content of the card
*/
@Composable
public fun Card(
modifier: Modifier = Modifier,
onClick: (() -> Unit)? = null,
enabled: Boolean = true,
interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
shape: CornerBasedShape = CardDefaults.Shape,
colors: CardColors = CardDefaults.cardColors(),
shadowStyle: DropShadow = CardDefaults.Shadow,
contentPadding: PaddingValues = CardDefaults.ContentPadding,
content: @Composable ColumnScope.() -> Unit
) {
val backgroundColor by colors.backgroundColor(enabled)
val contentColor by colors.contentColor(enabled)
val borderColor by colors.borderColor(enabled)
CompositionLocalProvider(LocalContentColor provides contentColor) {
Box(
modifier = modifier
.dropShadow(shadowStyle)
.clip(shape)
.semantics(mergeDescendants = false) {
isTraversalGroup = true
}
.clickable(
interactionSource = interactionSource,
indication = LocalIndication.current,
enabled = enabled && onClick != null,
onClick = onClick ?: {}
)
.ifTrue(borderColor.isSpecified) {
border(1.dp, borderColor, shape)
}
.background(backgroundColor, shape)
.padding(contentPadding),
propagateMinConstraints = true
) {
Column(content = content)
}
}
}