Stop writing 20 @Preview functions — explore every Jetpack Compose configuration at runtime.
PreviewSandbox is an interactive configuration wrapper for Jetpack Compose that eliminates configuration bloat. Instead of creating redundant static previews for Dark Mode, RTL, and various Font Scales, you wrap your UI in a single PreviewSandbox and toggle these settings on-the-fly via an interactive control panel.
- 🌓 Theme Toggling: Switch between Light and Dark mode instantly.
- 🌍 Runtime Locales: Cycle through your supported languages (strings, plurals, date formats).
- 📏 Dynamic Font Scaling: Test accessibility ranges from 1.0× up to 2.0×.
↔️ RTL/LTR Mirroring: Test layout mirroring independently or based on locale.- 🎨 Dynamic Color: Toggle Material You dynamic color schemes.
- 🖼️ Wallpapers & Backgrounds: Test overlays or transparent UIs against custom painters or colors.
- ♿ Accessibility Aids: Toggle Bold Text and High Contrast modes.
- 💾 State Persistence: Your sandbox configuration survives screen rotations.
- 🕵️ Ghost Mode: Automatically stays invisible in static previews; only appears in Interactive Mode or on-device.
Currently, PreviewSandbox is a single-file utility designed to be dropped into your design system module.
- Copy
PreviewSandbox.ktto your project. - Ensure you have the
kotlinx-collections-immutabledependency in yourbuild.gradle:implementation("org.jetbrains.kotlinx:kotlinx-collections-immutable:0.4.0")
Wrap your screen preview with PreviewSandbox. Pass your app's theme wrapper to the theme slot to propagate sandbox state.
@Preview
@Composable
private fun MyScreenPreview() {
PreviewSandbox(
theme = { state, content ->
AppTheme(
darkTheme = state.isDark,
dynamicColor = state.isDynamicColor,
isBoldText = state.isBoldText,
isHighContrast = state.isHighContrast
) {
content()
}
}
) {
MyScreen()
}
}Use ThemeCapabilities to control which toggles appear in the panel:
val MyCapabilities = ThemeCapabilities(
supportedLocales = persistentListOf(
SandboxLocale("en", "English"),
SandboxLocale("ar", "Arabic")
),
supportsRtl = true,
supportsWallpaper = true
)Jetpack Compose static previews are great, but they don't scale. Testing 4 locales across 5 font scales and 2 themes results in 40 previews for a single screen. PreviewSandbox solves this by moving configuration from compile-time branching to run-time exploration.
Read the full deep-dive on Medium.
- Min SDK: 24+ (Requires
LocaleListfor runtime locale switching). - Jetpack Compose: 1.5.0+
- Dependency:
kotlinx-collections-immutable
This is a developer tool born out of frustration with preview boilerplate. Feel free to open issues or PRs if you have ideas for new configuration axes (e.g., Network status simulation, Window size classes).
Georgios (SeijinD)
Android Developer | GitHub | LinkedIn
“Build better UI, faster.”
