---
title: "Conditional: repeat"
description: Play a change effect now and then while a condition is true.
---

Repeat plays a change effect when a condition becomes true and again at a fixed interval while it stays true. Use it for a subtle nudge, such as a shine across an "Update available" button every few seconds.

## Usage

The sample pulses a badge every two seconds while there is unread mail.

```kotlin
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.unit.dp
import com.jantursky.kapow.ChangeEffect
import com.jantursky.kapow.ConditionalEffect
import com.jantursky.kapow.conditionalEffect
import kotlin.time.Duration.Companion.seconds

@Composable
fun MailBadge(hasUnread: Boolean) {
    Box(
        Modifier
            .size(12.dp)
            .background(Color.Red, CircleShape)
            .conditionalEffect(
                condition = hasUnread,
                effect = ConditionalEffect.repeat(ChangeEffect.pulse(shape = CircleShape, color = Color.Red), every = 2.seconds),
            ),
    )
}
```

## Parameters

| Parameter | Default | Description |
| --- | --- | --- |
| `effect` | required | The change effect to play. |
| `every` | required | The time between plays. Anything shorter than `ConditionalEffect.MinRepeatInterval` (1/15 s) is raised to it. |
| `initialDelay` | `Duration.ZERO` | How long to wait after the condition turns true before the first play. |
| `maxCount` | `null` | How many times to play in all, per time the condition turns true. Null keeps playing while it holds. Must be positive. |
| `jitter` | `0f` | How much each wait varies, as a share of `every`, from 0 (exact) to 1. Waits never go below `MinRepeatInterval`. |
| `seed` | `0` | The start of the random numbers that vary the waits. The same seed gives the same rhythm. |

## Reduced motion

Each repetition plays the wrapped effect's reduced version.

## Notes

- The first play is immediate, including when the condition is already true on first composition.
- When the condition turns false, no more plays are scheduled. A play that is already running finishes.
- The wrapped effect keeps its cooldown. If `every` is shorter than the cooldown, some repetitions are skipped.
- You can wrap a [delayed](/effects/change-delay) effect.

## Flash safety

When the repeated effect flashes (`flash`, `glitch`), `LocalKapowMaxFlashesPerSecond` set to N starts the plays at least 1/N seconds apart, even when `every` is shorter. Effects that only move or emit particles are not paced. Off by default. The limit is a cap on the rate, not a claim of WCAG 2.3.1 conformance. See the [accessibility guide](/guides/accessibility).

## Live example

<iframe class="live-example" src="https://kapow-demo.vercel.app/#conditional-repeat" title="Live example: conditional-repeat" loading="lazy" allow="autoplay"></iframe>
