Fiori Horizon List Cards¶
Design¶
The Fiori Horizon List Card displays a list of similar cells inside a card view. The List Card can also have a header at the top and/or action buttons at the bottom of the list. The List Card supports both Light mode and Dark mode, determined by the device's settings.
![]() |
![]() |
|---|---|
![]() |
|---|
Development¶
The Fiori Horizon List Card is implemented entirely using Jetpack Compose, including a Composable FioriHorizonTheme. To understand the fundamentals of Jetpack Compose, refer to the Android Developer's documentation.
The fiori-horizon-cards module provides two UI components for application developers to use out of the box:
ListCard: a UI component to display a single List Card.ListCardGrid: a UI component to display a series of List Cards in a vertically scrollable grid that is responsive to different screen sizes.
Usage in an Application¶
This section describes how to use the List Card components in an application.
![]() |
![]() |
|---|---|

1. How to Create a ListCard¶
ListCard is a Composable function that takes four parameters:
- A
ListCardDatathat specifies the data to be displayed on the card - A
Modifierthat is used to define the height and width of the card and/or aTestTagneeded for Unit Tests. A defaultlistCardModifieris predefined to set the minimum height and width requirements. - A
ListCardTextColorsto customize the default text colors used. - A
ListCardTextStylesto customize the default text styles used.
@Composable
fun ListCard(
data: ListCardData,
modifier: Modifier = listCardModifier,
textColors: ListCardTextColors = ListCardDefaults.textColors(),
textStyles: ListCardTextStyles = ListCardDefaults.textStyles()
) {
val uiState = rememberListCardUiState(data = data)
ListCardContent(
darkTheme = isSystemInDarkTheme(),
uiState = uiState,
modifier = modifier,
textColors = textColors,
textStyles = textStyles
)
}
An object of the ListCardData has to be passed in from the application in order to create a ListCard.
@Parcelize
data class ListCardData(
val listCells: @RawValue List<ListCell>,
val header: String? = null,
val imageThumbnail: @RawValue ImageThumbnail? = null,
val menuItems: @RawValue List<MenuItem>? = listOf(),
val primaryActionButton: @RawValue ActionButton? = null,
val secondaryActionButton: @RawValue ActionButton? = null,
val cardStyles: @RawValue CardStyles? = null
) : Parcelable
data class ListCell(
val title: String,
val subtitle: String? = null,
val footnote: String? = null,
val status: ListCellStatus? = null,
val imageThumbnail: @RawValue ImageThumbnail? = null,
val listCellAction: ListCellAction,
val clickable: Boolean = true,
val onClick: () -> Unit?
)
Creating a ListCard can be as simple as the following (if there is no need to provide a custom Modifier):
FioriHorizonTheme(darkTheme = false) {
val listCardData = remember { generateListCardExample() }
ListCard(data = listCardData)
}
You can customize the ListCard's style, including Action Button styles and card background color, by supplying new values in the ListCardData. For example, to change the background color of the ActionButton on the ListCells of a ListCard from the default color to green:
val LC_LISTCELL4 = ListCell(
title = "Maternity Leave",
subtitle = "09/10/21 - 01/12/22",
footnote = "Leave Request",
imageThumbnail = ImageThumbnail(
imageType = ImageType.RESOURCE,
resId = R.drawable.angular_square,
imageDesc = "Image Description"
),
listCellAction = ListCellAction(
actionType = ListCellActionType.TEXT,
textActionButton = ActionButton("Approve", {}, false, Color.Green, Color.Green)
),
clickable = true,
onClick = {}
)
val LISTCARDEXAMPLE4 = ListCardData(
listCells = List(5){ LC_LISTCELL4},
header = LC_HEADER,
imageThumbnail = LC_IMAGETHUMBNAIL,
primaryActionButton = LC_PRIMARYACTIONBUTTON,
secondaryActionButton = LC_SECONDARYACTIONBUTTON,
menuItems = LC_MENUITEMSWITHICONS
)
fun generateListCardExample(): ListCardData {
return LISTCARDEXAMPLE4
}
FioriHorizonTheme(darkTheme = false) {
val listCardData = remember { generateListCardExample() }
ListCard(data = listCardData)
}
When this card is drawn on the screen, the Approve buttons will be green.
![]() |
![]() |
|---|---|
2. How to Create a ListCardGrid¶
To display a series of ListCards on the screen, use a ListCardGrid.
A ListCardGrid is defined as a Composable function in the fiori-horizon-cards module. In order to create a ListCardGrid, an application only needs to know the signatures of this function.
@Composable
fun ListCardGrid(
cardList: List<ListCardData>,
screenType: Enum<ScreenType>,
modifier: Modifier = Modifier
){
...
}
An application should pass in a list of ListCardData objects as well as an Enum value for ScreenType. For example:
FioriHorizonTheme {
val listCardDataList = remember { generateListCardList() }
val screenType = getScreenType()
ListCardGrid(
cardList = listCardDataList,
screenType = screenType,
modifier = Modifier.then(Modifier.wrapContentHeight(Alignment.Top))
)
}
Within the fiori-horizon-cards module, a utility Composable function is provided for applications to detect the ScreenType based on the Android Developers' recommendation documented in Support different screen sizes.
@Composable
fun getScreenType(): ScreenType {
val screenWidth =
LocalContext.current.resources.displayMetrics.widthPixels.dp / LocalDensity.current.density
return when {
screenWidth < 600.dp -> ScreenType.SMALL
screenWidth >= 600.dp && screenWidth < 840.dp -> ScreenType.MEDIUM
screenWidth > 840.dp -> ScreenType.LARGE
else -> ScreenType.SMALL
}
}
In order to create the ListCardGrid with custom text color or styles, use the following Composable function:
@Composable
fun ListCardGrid(
cardList: List<ListCardDataCustomStyleForCollection>,
screenType: Enum<ScreenType>,
modifier: Modifier = Modifier
) {
...
}
Where the ListCardDataCustomStyleForCollection is comprised of:
data class ListCardDataCustomStyleForCollection(
val data: ListCardData,
val textColors: @RawValue ListCardTextColors? = null,
val textStyles: @RawValue ListCardTextStyles? = null
) : Parcelable
3. How to Customize ListCard Text Color and Style¶
The default colors and styles of the text in a List Card adhere to the Fiori Horizon design. However, users can also customize them with their own colors and styles. In order to change the text color and text style, use the ListCardDefaults.textColors() and ListCardDefaults.textStyles() Composable functions, respectively, and pass in the required colors and styles for the different texts seen within the List Card.
val customTitleColor = MaterialTheme.fioriHorizonAttributes.SapFioriColorSemanticCritical
val customSubtitleColor = MaterialTheme.fioriHorizonAttributes.SapFioriColorAccent4
val customHeaderColor = MaterialTheme.fioriHorizonAttributes.SapFioriColorSemanticNegative
val customFootnoteColor = MaterialTheme.fioriHorizonAttributes.SapFioriColorAccent12
val customTitleStyle = FioriTextStyleH6
val customSubtitleStyle = FioriTextStyleSubtitle2
val customFootnoteStyle = FioriTextStyleSubtitle3
val customHeaderStyle = FioriTextStyleBody1
val customStatusStyle = FioriTextStyleBody1
FioriHorizonTheme {
ListCard(
data = generateListCardExample(),
textColors = ListCardDefaults.textColors(
titleColor = customTitleColor,
subtitleColor = customSubtitleColor,
headerColor = customHeaderColor,
footnoteColor = customFootnoteColor
),
textStyles = ListCardDefaults.textStyles(
titleStyle = customTitleStyle,
subtitleStyle = customSubtitleStyle,
footnoteStyle = customFootnoteStyle,
headerStyle = customHeaderStyle,
statusStyle = customStatusStyle
)
)
}




