Documentation
Make it yours
App integration
Embed Composium in your Android app, reuse scenes in Android Studio previews, and handle wrappers and window insets.
Android Studio Previews
A scene can be rendered from a regular Android Studio @Preview through the
RenderPreview extension:
import androidx.compose.runtime.Composable
import androidx.compose.ui.tooling.preview.Preview
import oleginvoke.com.composium.RenderPreview
@Preview(showBackground = true, widthDp = 420, heightDp = 720)
@Composable
private fun PrimaryButtonPreview() {
PrimaryButtonScene.RenderPreview()
}
Every preview owns an independent scene scope and uses the scene's default parameter values.
Custom Scene Wrappers
If several scenes need the same preview chrome, create a small project-local helper around scene(...).
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.unit.dp
import oleginvoke.com.composium.SceneDelegate
import oleginvoke.com.composium.SceneScope
import oleginvoke.com.composium.scene
fun sceneWithFrame(
group: String? = null,
name: String? = null,
content: @Composable SceneScope.() -> Unit,
): SceneDelegate = scene(
group = group,
name = name,
) { contentPadding ->
Box(
modifier = Modifier
.fillMaxSize()
.padding(contentPadding)
.background(Color(0xFFF7F7F7))
.padding(24.dp),
contentAlignment = Alignment.Center,
) {
content()
}
}
This wrapper consumes contentPadding in its own frame before invoking the caller's content, like the sample app's sceneWithDecorator. Alternatively, a wrapper can expose and forward the padding-aware content signature directly:
fun sceneForwardingPadding(
group: String? = null,
name: String? = null,
content: @Composable SceneScope.(PaddingValues) -> Unit,
): SceneDelegate = scene(
group = group,
name = name,
content = content,
)
Wrappers that expose SceneScope.(PaddingValues) -> Unit are checked by the same bundled lint detector, so their callers must apply or forward the argument, or use the intentional full-bleed suppression.
Use that helper for scenes that should share the same frame:
val PrimaryButtonScene by sceneWithFrame(group = "Buttons") {
PrimaryButton(text = "Save", onClick = {})
}
Window Insets
ComposiumScreen() accounts for system bars and display cutouts by default. It keeps the background
edge-to-edge while positioning its own UI and providing the appropriate contentPadding to scenes.
Floating tools do not contribute to scene padding. Keyboard handling is separate from these default insets.
When embedding Composium inside a Scaffold, apply and consume the outer padding:
Scaffold { innerPadding ->
ComposiumScreen(
modifier = Modifier
.padding(innerPadding)
.consumeWindowInsets(innerPadding),
)
}
Composium excludes insets already consumed by its parents. A plain Modifier.padding(...) does not
mark insets as consumed. If your container handles all system padding itself, disable Composium's
insets explicitly:
ComposiumScreen(
modifier = Modifier.padding(innerPadding),
contentWindowInsets = WindowInsets(0),
)
The default is available as ComposiumDefaults.contentWindowInsets. You can also supply custom
WindowInsets to control which sides and inset types Composium handles.
This configures content placement; it does not enable edge-to-edge on the activity's window.