Skip to content

Card

Card is a basic container component in COUI, used to hold related content and actions. It provides a card container with COUI style, suitable for scenarios such as information display and content grouping. Supports both static display and interactive modes.

Import

kotlin
import io.github.suqi8.coui.kmp.basic.Card
import io.github.suqi8.coui.kmp.utils.PressFeedbackType // If using interactive card

Basic Usage

The Card component can be used to wrap and organize content (static card):

kotlin
Card {
    Text("This is card content")
}

Properties

Card Properties

Property NameTypeDescriptionDefault ValueRequiredApplies To
modifierModifierModifier applied to the cardModifierNoAll
cornerRadiusDpCard corner radiusCardDefaults.CornerRadiusNoAll
insideMarginPaddingValuesCard inner paddingCardDefaults.InsideMarginNoAll
colorsCardColorsCard color configurationCardDefaults.defaultColors()NoAll
pressFeedbackTypePressFeedbackTypeFeedback type when pressedPressFeedbackType.TintNoInteractive
showIndicationBooleanShow indication on interactionfalseNoInteractive
holdDownStateBooleanWhether the card is in the pressed statefalseNoInteractive
onClick(() -> Unit)?Callback when clickednullNoInteractive
onLongPress(() -> Unit)?Callback when long pressednullNoInteractive
content@Composable ColumnScope.() -> UnitComposable function for card content area-YesAll

WARNING

Some properties are only available when creating an interactive card!

CardDefaults Object

The CardDefaults object provides default values and color configurations for the card component.

Constants

Constant NameTypeDescriptionDefault Value
CornerRadiusDpCard corner radius12.dp
InsideMarginPaddingValuesCard inner paddingPaddingValues(0.dp)

Methods

Method NameTypeDescription
defaultColors()CardColorsThe default color for card

CardColors Class

Property NameTypeDescription
colorColorDefault background color of card
contentColorColorDefault content color of card
pressedColorColorFill color the card animates towards while pressed (Tint feedback)

PressFeedbackType Options

OptionDescription
NoneNo press feedback
TintAnimates the fill towards pressedColor while pressed or held down (COUI card feedback, default)
SinkSinks (scales down) slightly when pressed
TiltTilts based on the touch position when pressed

Advanced Usage

Custom Style Card

kotlin
Card(
    cornerRadius = 8.dp,
    insideMargin = PaddingValues(16.dp),
    colors = CardDefaults.defaultColors(
        color = COUITheme.colorScheme.primaryVariant
    ),
) {
    Text("Custom Style Card")
}

Content-Rich Card

kotlin
Card(
    modifier = Modifier.padding(16.dp),
    insideMargin = PaddingValues(16.dp)
) {
    Text(
        text = "Card Title",
        style = COUITheme.textStyles.title2
    )
    Spacer(modifier = Modifier.height(8.dp))
    Text(
        text = "This is a detailed description of the card, which can contain multiple lines of text."
    )
    Spacer(modifier = Modifier.height(16.dp))
    Row(
        modifier = Modifier.fillMaxWidth(),
        horizontalArrangement = Arrangement.End
    ) {
        TextButton(
            text = "Cancel",
            onClick = { /* Handle cancel event */ }
        )
        Spacer(modifier = Modifier.width(8.dp))
        TextButton(
            text = "Confirm",
            colors = ButtonDefaults.textButtonColorsPrimary(), // Use theme colors
            onClick = { /* Handle confirm event */ }
        )
    }
}

Cards in a List

kotlin
LazyColumn {
    items(5) { index ->
        Card(
            modifier = Modifier
                .fillMaxWidth()
                .padding(horizontal = 16.dp, vertical = 8.dp),
            insideMargin = PaddingValues(16.dp)
        ) {
            Text("List Item ${index + 1}")
        }
    }
}

Interactive Card

kotlin
Card(
    modifier = Modifier.padding(16.dp),
    // pressFeedbackType defaults to PressFeedbackType.Tint: the fill animates
    // towards CardColors.pressedColor while pressed (COUI card press feedback)
    onClick = {/* Handle click event */ },
    onLongPress = {/* Handle long press event */ }
) {
    Text("Interactive Card")
}
kotlin
Card(
    modifier = Modifier.padding(16.dp),
    pressFeedbackType = PressFeedbackType.Sink, // Set press feedback to sink effect
    showIndication = true, // Show indication on click
    onClick = {/* Handle click event */ },
) {
    Text("Interactive Card (Sink)")
}

Card Group Row Positions

COUI grows the rounded outer edges of a card group by coui_list_card_head_or_tail_padding (2dp). Pass a CardListPosition to the preference rows stacked inside a Card so each row gets the padding on the edges that are actually rounded. CardListPosition.None (the default) adds nothing, so existing call sites are unaffected.

PositionExtra topExtra bottomTotal
None (default)0dp0dp+0dp
Head2dp0dp+2dp
Middle0dp0dp+0dp
Tail0dp2dp+2dp
Full (only row)2dp2dp+4dp

Use cardListPositionOf(index, count) to derive the position while iterating a list. It mirrors COUI's COUICardListHelper.getPositionInGroup(int, int), returning Full when count == 1.

kotlin
val options = listOf("Every day", "Workdays only", "Never")

Card {
    options.forEachIndexed { index, option ->
        if (index > 0) HorizontalDivider(Modifier.padding(horizontal = 16.dp))
        MarkPreference(
            title = option,
            checked = selected == index,
            onClick = { selected = index },
            cardListPosition = cardListPositionOf(index, options.size),
        )
    }
}

Changelog

Released under the Apache-2.0 License