---
title: "placeholder"
description: "Draws a placeholder shape over the top of a composable and animates a wipe off effect to remove
the placeholder. Typically used whilst content is 'loading' and then 'revealed'.

Example of a [Chip] with icon and a label that put placeholders over individual content slots:


Example of a [Chip] with icon and a primary and secondary labels that draws another [Chip] over
the top of it when waiting for placeholder data to load:


The [placeholderState] determines when to 'show' and 'wipe off' the placeholder.

NOTE: The order of modifiers is important. If you are adding both [Modifier.placeholder] and
[Modifier.placeholderShimmer] to the same composable then the shimmer must be first in the
modifier chain. Example of [Text] composable with both placeholderShimmer and placeholder
modifiers."
type: "composable"
---

<div class='type'>Composable Function</div>


<a id='references'></a>

<div class='sourceset sourceset-android'>Android</div>


```kotlin
@ExperimentalWearMaterialApi
@Composable
public fun Modifier.placeholder(
    placeholderState: PlaceholderState,
    shape: Shape = MaterialTheme.shapes.small,
    color: Color =
        MaterialTheme.colors.onSurface
            .copy(alpha = 0.1f)
            .compositeOver(MaterialTheme.colors.surface),
): Modifier
```


Draws a placeholder shape over the top of a composable and animates a wipe off effect to remove
the placeholder. Typically used whilst content is 'loading' and then 'revealed'.

Example of a `Chip` with icon and a label that put placeholders over individual content slots:


Example of a `Chip` with icon and a primary and secondary labels that draws another `Chip` over
the top of it when waiting for placeholder data to load:


The `placeholderState` determines when to 'show' and 'wipe off' the placeholder.

NOTE: The order of modifiers is important. If you are adding both `Modifier.placeholder` and
`Modifier.placeholderShimmer` to the same composable then the shimmer must be first in the
modifier chain. Example of `Text` composable with both placeholderShimmer and placeholder
modifiers.

#### Parameters

| | |
| --- | --- |
| placeholderState | determines whether the placeholder is visible and controls animation effects for the placeholder. |
| shape | the shape to apply to the placeholder |
| color | the color of the placeholder. |





## Code Examples
### ChipWithIconAndLabelAndPlaceholders
```kotlin
/**
 * This sample applies placeholders directly over the content that is waiting to be loaded. This
 * approach is suitable for situations where the developer is confident that the stadium shaped
 * placeholder will cover the content in the period between when it is loaded and when the
 * placeholder visual effects will have finished.
 */
@OptIn(ExperimentalWearMaterialApi::class)
@Composable
fun ChipWithIconAndLabelAndPlaceholders() {
    var labelText by remember { mutableStateOf("") }
    var iconResource: Int? by remember { mutableStateOf(null) }
    val chipPlaceholderState = rememberPlaceholderState {
        labelText.isNotEmpty() && iconResource != null
    }
    Chip(
        onClick = { /* Do something */ },
        enabled = true,
        label = {
            Text(
                text = labelText,
                maxLines = 2,
                overflow = TextOverflow.Ellipsis,
                modifier = Modifier.fillMaxWidth().placeholder(chipPlaceholderState),
            )
        },
        icon = {
            Box(modifier = Modifier.size(ChipDefaults.IconSize).placeholder(chipPlaceholderState)) {
                if (iconResource != null) {
                    Icon(
                        painter = painterResource(id = R.drawable.ic_airplanemode_active_24px),
                        contentDescription = "airplane",
                        modifier =
                            Modifier.wrapContentSize(align = Alignment.Center)
                                .size(ChipDefaults.IconSize)
                                .fillMaxSize(),
                    )
                }
            }
        },
        colors =
            PlaceholderDefaults.placeholderChipColors(
                originalChipColors = ChipDefaults.primaryChipColors(),
                placeholderState = chipPlaceholderState,
            ),
        modifier = Modifier.fillMaxWidth().placeholderShimmer(chipPlaceholderState),
    )
    // Simulate content loading completing in stages
    LaunchedEffect(Unit) {
        delay(2000)
        iconResource = R.drawable.ic_airplanemode_active_24px
        delay(1000)
        labelText = "A label"
    }
    if (!chipPlaceholderState.isShowContent) {
        LaunchedEffect(chipPlaceholderState) { chipPlaceholderState.startPlaceholderAnimation() }
    }
}
```
### ChipWithIconAndLabelsAndOverlaidPlaceholder
```kotlin
/**
 * This sample places a [Chip] with placeholder effects applied to it on top of the [Chip] that
 * contains the actual content.
 *
 * This approach is needed in situations where the developer wants a higher degree of control over
 * what is shown as a placeholder before the loaded content is revealed. This approach can be used
 * when there would otherwise be content becoming visible as it is loaded and before the
 * placeholders have been wiped-off to reveal the content underneath, e.g. If the content contains
 * left|top aligned Text that would be visible in the part of the content slot not covered by the
 * stadium placeholder shape.
 */
@OptIn(ExperimentalWearMaterialApi::class)
@Composable
fun ChipWithIconAndLabelsAndOverlaidPlaceholder() {
    var labelText by remember { mutableStateOf("") }
    var secondaryLabelText by remember { mutableStateOf("") }
    var iconResource: Int? by remember { mutableStateOf(null) }
    val chipPlaceholderState = rememberPlaceholderState {
        labelText.isNotEmpty() && secondaryLabelText.isNotEmpty() && iconResource != null
    }
    Box {
        if (chipPlaceholderState.isShowContent || chipPlaceholderState.isWipeOff) {
            Chip(
                onClick = { /* Do something */ },
                enabled = true,
                label = {
                    Text(
                        text = labelText,
                        maxLines = 1,
                        overflow = TextOverflow.Ellipsis,
                        modifier = Modifier.fillMaxWidth(),
                    )
                },
                secondaryLabel = {
                    Text(
                        text = secondaryLabelText,
                        maxLines = 1,
                        overflow = TextOverflow.Ellipsis,
                        modifier = Modifier.fillMaxWidth(),
                    )
                },
                icon = {
                    if (iconResource != null) {
                        Icon(
                            painter = painterResource(id = R.drawable.ic_airplanemode_active_24px),
                            contentDescription = "airplane",
                            modifier =
                                Modifier.wrapContentSize(align = Alignment.Center)
                                    .size(ChipDefaults.IconSize),
                        )
                    }
                },
                colors = ChipDefaults.gradientBackgroundChipColors(),
                modifier = Modifier.fillMaxWidth(),
            )
        }
        if (!chipPlaceholderState.isShowContent) {
            Chip(
                onClick = { /* Do something */ },
                enabled = true,
                label = {
                    Box(
                        modifier =
                            Modifier.fillMaxWidth()
                                .height(16.dp)
                                .padding(top = 1.dp, bottom = 1.dp)
                                .placeholder(placeholderState = chipPlaceholderState)
                    )
                },
                secondaryLabel = {
                    Box(
                        modifier =
                            Modifier.fillMaxWidth()
                                .height(16.dp)
                                .padding(top = 1.dp, bottom = 1.dp)
                                .placeholder(placeholderState = chipPlaceholderState)
                    )
                },
                icon = {
                    Box(
                        modifier =
                            Modifier.size(ChipDefaults.IconSize).placeholder(chipPlaceholderState)
                    )
                    // Simulate the icon becoming ready after a period of time
                    LaunchedEffect(Unit) {
                        delay(2000)
                        iconResource = R.drawable.ic_airplanemode_active_24px
                    }
                },
                colors =
                    PlaceholderDefaults.placeholderChipColors(
                        placeholderState = chipPlaceholderState
                    ),
                modifier = Modifier.fillMaxWidth().placeholderShimmer(chipPlaceholderState),
            )
        }
    }
    // Simulate data being loaded after a delay
    LaunchedEffect(Unit) {
        delay(2500)
        secondaryLabelText = "A secondary label"
        delay(500)
        labelText = "A label"
    }
    if (!chipPlaceholderState.isShowContent) {
        LaunchedEffect(chipPlaceholderState) { chipPlaceholderState.startPlaceholderAnimation() }
    }
}
```
### TextPlaceholder
```kotlin
/**
 * This sample applies a placeholder and placeholderShimmer directly over a single composable.
 *
 * Note that the modifier ordering is important, the placeholderShimmer must be before the
 * placeholder in the modifier chain - otherwise the shimmer will be drawn underneath the
 * placeholder and will not be visible.
 */
@OptIn(ExperimentalWearMaterialApi::class)
@Composable
fun TextPlaceholder() {
    var labelText by remember { mutableStateOf("") }
    val chipPlaceholderState = rememberPlaceholderState { labelText.isNotEmpty() }
    Text(
        text = labelText,
        overflow = TextOverflow.Ellipsis,
        textAlign = TextAlign.Center,
        modifier =
            Modifier.width(90.dp)
                .placeholderShimmer(chipPlaceholderState)
                .placeholder(chipPlaceholderState),
    )
    // Simulate content loading
    LaunchedEffect(Unit) {
        delay(3000)
        labelText = "A label"
    }
    if (!chipPlaceholderState.isShowContent) {
        LaunchedEffect(chipPlaceholderState) { chipPlaceholderState.startPlaceholderAnimation() }
    }
}
```

