Override theme tokens for one subtree
Use UiThemeOverride when one semantic section needs a different color, typography, shape, control
sizing, interaction, or overlay family. It derives a nested immutable theme snapshot and restores
the parent after the subtree. Read the theme architecture for the full
precedence and renderer boundary.
Transform only the required families
The transforming overload starts from the current family. Unspecified families preserve their parent values:
fun UiTreeBuilder.AccentPanel() {
UiThemeOverride(
colors = { copy(primary = 0xFF6750A4.toInt()) },
shapes = { copy(medium = large) },
) {
Column {
Text("Only this subtree uses the accent theme")
Button("Continue", onClick = {})
}
}
}
Use the value overload when the application already owns complete replacement families. Replacing
colors without an explicit stateColors replacement re-derives state colors, preventing an old
pressed, selected, or disabled palette from leaking into the new scheme.
Choose the correct override level
UiThemeOverride changes semantic defaults for every participating component in a subtree. A
component-owned XxxOverrides provider changes sparse appearance slots for only that component
family. An instance appearance remains the most specific value.
Use a component override for one Button border, TextField decoration, or control interaction layer.
Use an application-defined uiLocalOf when the value is an application semantic concept that does
not belong in the framework theme. Do not put controlled state, callbacks, keyboard policy,
navigation, lifecycle, resource handles, or renderer platform types into either appearance model.
Basic primitives accept complete resolved styles and do not consume sparse overrides. Renderer
receives resolved NodeSpec values and never reads UiThemeOverride directly.
Verify the task
Compile with ./gradlew :samples:tutorials:compileDebugKotlin, then verify one page containing the
parent theme, the nested panel, and a sibling after the panel:
- Change the parent theme and confirm inherited fields inside the panel update.
- Confirm the panel's primary color and medium shape remain overridden.
- Press, focus, select, and disable controls in the panel; their state colors must match the overridden semantic palette.
- Confirm the sibling after the panel uses the unchanged parent snapshot.
- Add a component-scope and instance override inside the panel and confirm the documented precedence remains instance, component scope, then theme scope.
Leaking the panel theme to a sibling, retaining parent state colors, or making a behavior change through an appearance object fails the task.