What problem does it solve?
It prevents reusable Jetpack Compose components from becoming hard to extend when visual content differs across call sites and parameters start turning into an ever-growing list of primitives and booleans.
Core Features & Use Cases
- Replace primitive content params with composable slots: delegate variable UI regions to caller-provided @Composable lambdas so the component defines structure while the caller defines content.
- Use scope receivers when the slot needs layout APIs: declare slots as @Composable RowScope.() -> Unit (or BoxScope/ColumnScope) when the slot is rendered inside that layout so callers can use weight, alignment, and scope-specific modifiers.
- Model optional UI as nullable slots: prefer (@Composable () -> Unit)? = null over empty-lambda defaults to clearly distinguish “absent” from “present but empty,” enabling the component to skip spacing and containers.
- Centralize common defaults in XxxDefaults: move reusable default slot content into a nearby Defaults object so the main component API stays clean and call sites remain concise.
- Use-case example: when designing a reusable settings/list row that might show an icon, a badge, a switch, or custom trailing content depending on the screen, slot the leading/headline/supporting/trailing regions instead of enumerating variants and flags.
Quick Start
Refactor your reusable Compose component so every caller-controlled visual region is exposed as a dedicated @Composable slot, using nullable slots for optional regions and a scope receiver only when the slot’s layout context needs it.