@when
A list of conditions in markup. The first one that holds renders; the rest are skipped.
Basic Usage
@when takes no subject. Each branch is a condition, an arrow, and the component
to render:
<Column>
@when {
status == Status.LOADING -> <CircularProgressIndicator />
status == Status.ERROR -> <Text>Failed to load</Text>
else -> <ContentView />
}
</Column> Which is Kotlin's subject-less when, and compiles to exactly that:
when {
status == Status.LOADING -> CircularProgressIndicator()
status == Status.ERROR -> Text(text = "Failed to load")
else -> ContentView()
} The rules
There are three, and the second is the one that catches people:
- Conditions are ordinary Kotlin. Comparisons, enum equality, null checks,
calls — anything that evaluates to a
Boolean. - A branch renders exactly one component. To show more than one thing, wrap
them in a
<Column>or<Box>. elseis optional. Without it, no branch matching means nothing renders — which is usually what you want in markup, and never a compile error.
condition -> { … }, and that does not compile here. A branch is one
component, written directly after the arrow.See it happen
var score = 72
<Column>
@when {
score >= 90 -> <Text color="#10b981">A</Text>
score >= 80 -> <Text color="#10b981">B</Text>
score >= 70 -> <Text color="#f59e0b">C</Text>
else -> <Text color="#ef4444">F</Text>
}
</Column>@when matches conditions top to bottom, and the first true branch wins — like a subject-less Kotlin when.
There is no subject form
Kotlin lets you write when (x) { is Loading -> … }, matching on the type
of a subject. Whitehall's @when does not: there is no parenthesised subject and no is pattern. Both are parse errors.
// Does not compile
@when (status) {
is Loading -> { <Text>Loading</Text> }
}
// Write this instead
@when {
status is Loading -> <Text>Loading</Text>
} Sealed class hierarchies still work — you just spell the check as a condition, the same as any
other. What you give up is the compiler proving the branches are exhaustive, since a
subject-less when used as a statement has nothing to be exhaustive over.
@when or @if
They compile to different Kotlin and neither is a shorthand for the other, but in markup the choice is mostly about how many branches you have.
| Use | When |
|---|---|
| @if / @else | One condition, or one condition with a fallback. Branches can hold several components. |
@when | Three or more branches over the same value, where a chain of else if would bury the shape. |
Common patterns
Loading, error, content
<Box fillMaxSize>
@when {
isLoading -> <CircularProgressIndicator />
error != null -> <Text color="#ef4444">{error}</Text>
items.isEmpty() -> <Text>Nothing here yet</Text>
else -> <ItemList items={items} />
}
</Box> Order matters, because the first true branch wins. Putting items.isEmpty() above
the error check would show an empty state during a failure.
Ranges
@when {
count == 0 -> <Text>None</Text>
count < 10 -> <Text>A few</Text>
else -> <Text>Lots</Text>
} See Also
- @if / @else — one condition, multi-component branches
- @for — iterating a list
- State & Reactivity — what the conditions read