Skip to content

Skeleton Loading

Skeleton loading informs users that the data is being loaded. A screen with skeleton loading placeholders can help reduce the perceived wait time and get users ready for the content. We provide skeleton loading placeholders for app teams to create a transition screen during loading.

Using Skeleton Loading

There are two steps involved in using skeleton loading:

  1. Enable the skeleton loading for composable objects
  2. Develop a triggering or controlling mechanism for the placeholder

Skeleton loading can be used as a modifier on a component level using a modifier or by using a PlaceHolder.

Skeleton Loading Modifiers

There are three kinds of modifiers:

  • Text
  • Square
  • Chart

Text Style Modifier

A text style modifier is used on single line or multi-line components. The modifier used for this is fioriSkeletonGrayedTextAnimated. The code snippet below shows how to enable the skeleton loading:

Text("My sample text", modifier = Modifier.fioriSkeletonGrayedTextAnimated())

Squared or Shaped Modifier

This modifier is fioriSkeletonGrayedSquareAnimated. The code snippet below shows how to create a circle-shaped skeleton indicator. The clip modifier clips the box and provides a shape, then the fioriSkeletonGrayedSquareAnimated modifier applies the skeleton to that shape. The order of these modifiers matters. For example, if there is a clipping shape, apply that modifier before the skeleton loading modifier. We recommend using skeletonloading as the last modifier.

Box(modifier = Modifier.clip(shape = CircleShape)
            .width(100.dp)
            .height(100.dp)
            .fioriSkeletonGrayedSquareAnimated()
        )

Chart Style Modifier

This modifier is specifically designed to be used for charts. The developer can specify a drawable resource to be placed at the center of the skeleton. If the resource is not specified, a default image of R.drawable.ic_sap_icon_horizontal_combination_chart is used.

The following example shows how to use the chart style modifier:

    Box(modifier = Modifier
            .width(100.dp)
            .height(100.dp)
            .fioriSkeletonGrayedSquareAnimated()
        ).fioriSkeletonGrayedChartAnimated( id = R.drawable.ic_sap_icon_picture)

Skeleton Loading Placeholders

If you need to completely replace the composable with a placeholder skeleton, use this approach.

To use a placeholder, enclose your composable unit with a placeholder call : PlacePlaceHolder. This takes the name of a predefined placeholder, of which there are 12, listed below.

For example, the following example replaces the composable code with genericPlaceHolder.

PlacePlaceHolder(genericPlaceHolder) {
    //Composable code
}

The following is the list of placeholders.

mobileCardPlaceHolderSmall

The mobile card small placeholder has the following visual aspect:

Mobile Card Place Holder (small)

mobileCardPlaceHolderMedium

The mobile card medium placeholder has the following visual aspect:

Mobile Card Place Holder (Medium)

mobileCardPlaceHolderLarge

The mobile card large placeholder has the following visual aspect:

Mobile Card Place Holder (Large)

objectHeaderPlaceHolder

The object header placeholder has the following visual aspect:

Object Card Place Holder

objectCellPlaceHolder

The object cell placeholder has the following visual aspect:

Object Card Place Holder

objectCardPlaceHolder

The object card placeholder has the following visual aspect:

Object Card Place Holder

genericPlaceHolder The generic placeholder has the following visual aspect:

Generic Place Holder

dataTablePlaceHolder

The data table placeholder has the following visual aspect: Data table Place Holder

kpiNumericPlaceHolderSmall

The KPI numeric placeholder (small) has the following visual aspect: KPI Numeric Place Holder(Small)

kpiNumericPlaceHolderLarge

The KPI numeric placeholder (large) has the following visual aspect: KPI Numeric Place Holder(Large)

kpiProgressPlaceHolderSmall

The KPI progress placeholder (small) has the following visual aspect:

KPI Progress Place Holder(Small)

kpiProgressPlaceHolderLarge

The KPI progress placeholder (large) has the following visual aspect:

KPI Progress Place Holder(Large)

Triggering Skeleton Loading

Skeleton loading is triggered by some event that indicates the readiness of data. For this purpose, the developer needs to implement a triggering mechanism.

This is done by defining an implementation of SkeletonLoading. Developers can customize the subclass and pass the trigger through a composable local provider.

Subclassing Skeleton Loading

The following snippet shows how to implement a subclass of skeleton loading. It is not necessary to use LaunchedEffect, but this is used here simply to indicate that this section should not be in a composable thread.

data class SkeletonLoadingInYourProgram(val loading: Boolean) :SkeletonLoading() {
    @Composable
    override fun loadData() : SkeletonLoading {
        isLoading = true

        LaunchedEffect (Unit){

            //Have your logging to make data ready here

            isLoading = false

        }
        return this
    }
}

Providing the Trigger Composables

The trigger is provided to your composable using a local composable provider. Enclose your code as shown in the following code snippet:

CompositionLocalProvider(LocalSkeletonLoading provides SkeletonLoadingInYourProgram(loading = false).loadData()) {

    //Your composable UI should be enclosed here

}

Last update: April 5, 2024