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
ListCardData
that specifies the data to be displayed on the card - A
Modifier
that is used to define the height and width of the card and/or aTestTag
needed for Unit Tests. A defaultlistCardModifier
is predefined to set the minimum height and width requirements. - A
ListCardTextColors
to customize the default text colors used. - A
ListCardTextStyles
to 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
)
)
}