styles
Use this skill to integrate the Jetpack Compose Styles API into an Android
- 0
- Installs
- —
- Rating
- —
- Success rate
- 6
- Files scanned
Security scan
Scan passedNo risky patterns were found in the scanned files.
Content sha256 09371b3b89e1653f… — run codexguild_scan_skills after installing to verify your local copy.
Static analysis is a first line of defense, not a guarantee. Read the source
SKILL.md
Limitations
- Warn the user that this skill is EXPERIMENTAL and requires updating to alpha version of Compose and opting in to the Experimental APIs.
- This skill only supports custom UI components and custom themes.
- This skill does not support Material Design component Styles.
Prerequisites
1. Upgrade dependencies
- The project must use
compileSdkversion 37 or higher. - The project must use
androidx.compose.foundation:foundationversion1.12.0-alpha01or higher. - Alternatively, the project must use Compose BOM version
2026.04.01or higher. - The API requires this exact package:
import androidx.compose.foundation.style.Style
2. Configure compiler options to enable experimental API
You must opt-in to the experimental API at the project level. Add the following
block to your module's build.gradle.kts:
kotlin {
compilerOptions {
jvmTarget = JvmTarget.fromTarget("17")
freeCompilerArgs.add("-opt-in=androidx.compose.foundation.style.ExperimentalFoundationStyleApi")
}
}
Core workflows and guides
Refer to the official documentation to complete specific development tasks:
- Basic Style Usage: To set backgrounds, sizes, and alignments on a component, follow the Compose Styles Fundamentals Guide.
- State and Transitions: To configure property changes for state shifts (like pressed or hovered), follow the Animations and State-Based Styling Guide.
- Architecture Trade offs: To decide when to use a Style versus a standard Modifier, follow the Styles versus Modifiers Comparison.
- Theme Level Integration: To connect style definitions with custom themes, follow Theming with Styles and Custom Themes in Compose.
Step-by-Step Migration Workflow
Step 1: Analyze theme structure
- Locate your central theme file (such as
Theme.kt). - Identify design tokens. Note references for colors, typography, and shapes (for example,
LocalColorScheme,LocalTypography, orLocalShapes). - If the project lacks Jetpack Compose dependencies, stop. Instruct the user to migrate to Jetpack Compose first.
- If the project imports
androidx.compose.material.MaterialTheme, recommend migrating to Material 3 before proceeding.
Step 2: Establish ComponentStyles
-
Create a new file named
ComponentStyles.ktin your theme directory. -
Define a top-level data class to hold your component styles, for example, the Jetsnack one is called
JetsnackStyles:object ExampleComponentStyles { val customButtonStyle: Style = { } val customTextFieldStyle: Style = { } } -
Expose this class through your custom theme with a static reference, don't use
CompositionLocalshere as it's not required.@Immutable class JetsnackTheme( // other Design system properties ) { companion object { val colors: CustomThemingWithStyles.JetsnackColors @Composable @ReadOnlyComposable get() = LocalJetsnackTheme.current.colors // ... // add helper static reference val styles: ComponentStyles = ComponentStyles } } -
Provide extensions on
StyleScopeto reference theme tokens directly if they are exposed usingCompositionLocals. For example:val StyleScope.colors: JetsnackColors get() = LocalJetsnackTheme.currentValue.colors val StyleScope.typography: androidx.compose.material3.Typography get() = LocalJetsnackTheme.currentValue.typography val StyleScope.shapes: Shapes get() = LocalJetsnackTheme.currentValue.shapes
Step 3: Migrate a component to Styles API
For each custom component (for example, CustomButton), complete the following
sequence:
- Establish a visual baseline (If an emulator is available):
- If you CANNOT run an Android emulator: Skip this step entirely and proceed to Step 2.
- If you CAN run an Android emulator: Perform the following to capture a baseline screenshot:
- Option A: Locate and run an existing screenshot test for the component.
- Option B (If no test exists): Create a test using the project's existing testing framework, then run it.
- Option C (If no framework exists): Create a minimal screenshot test using UI Automator or Espresso, then run it.
- Remove individual styling parameters : Remove styling parameters such as
backgroundColor,shape,textStyle, andcontentPaddingfrom the signature - anything thatStyleScopesupports. - Add the style parameter : Add
style: Style = Styleto the function signature. Always ensure the default value is exactlyStyle(e.g.,style: Style = Style) and not a specific style default likeChipStyleDefaultor any other value. - Declare state tracking : If the component is interactable, create a
MutableStyleStateusing the interaction source. Update state fields (such asisEnabled) inside the Composable to track the state correctly. - Apply styleable modifier : Replace specific layout modifiers on the root element with
Modifier.styleable(). - Move defaults to ComponentStyles : Move hardcoded values from the component definition to a dedicated
Styleinstance inComponentStyles.kt. - Validate component: Compare the baseline screenshot image taken at the start with the rendered Compose Preview of the new composable. Ignore string content; focus on layout and styling. Iterate on the Compose code until visual parity is achieved. Once verified, write a Compose UI test for the new composable.
Migration example
Before Migration:
@Composable
fun CustomButton(
onClick: () -> Unit,
modifier: Modifier = Modifier,
backgroundColor: Color = JetsnackTheme.colors.brandLight,
disabledBackgroundColor: Color = JetsnackTheme.colors.brandSecondary,
shape: Shape = JetsnackTheme.shapes.extraLarge,
textStyle: TextStyle = JetsnackTheme.typography.labelLarge,
enabled: Boolean = true,
content: @Composable RowScope.() -> Unit,
) {
val interactionSource = remember { MutableInteractionSource() }
Row(
modifier
.clickable(onClick = onClick, indication = null, interactionSource = interactionSource)
.background(if (enabled) backgroundColor else disabledBackgroundColor, shape)
.defaultMinSize(58.dp, 40.dp),
horizontalArrangement = Arrangement.Center,
verticalAlignment = Alignment.CenterVertically,
content = content,
)
}
After Migration:
// Exposed via ComponentStyles.kt
object ComponentStyles {
val buttonStyle = Style {
background(colors.brandLight)
shape(shapes.extraLarge)
minWidth(58.dp)
minHeight(40.dp)
textStyle(typography.labelLarge)
disabled {
background(colors.brandSecondary)
}
}
}
@Composable
fun CustomButton(
onClick: () -> Unit,
modifier: Modifier = Modifier,
style: Style = Style,
enabled: Boolean = true,
content: @Composable RowScope.() -> Unit,
) {
val interactionSource = remember { MutableInteractionSource() }
val styleState = rememberUpdatedStyleState(interactionSource) {
it.isEnabled = enabled
}
Row(
modifier
.clickable(onClick = onClick, indication = null, interactionSource = interactionSource)
.styleable(styleState, JetsnackTheme.styles.buttonStyle, style),
horizontalArrangement = Arrangement.Center,
verticalAlignment = Alignment.CenterVertically,
content = content,
)
}
Step 4: Validate Changes
- Build the project. Verify that there are no compilation errors.
- Run your module's screenshot tests.
- Compare visual outputs of the whole app between the previous and updated components. Verify that no visual layout regressions occur.
Files
6- SKILL.md
c8c93b1c938.8 KB - references/android/develop/ui/compose/designsystems/custom.md
80f55504d513.9 KB - references/android/develop/ui/compose/styles/fundamentals.md
79aec0b42e13.9 KB - references/android/develop/ui/compose/styles/state-animations.md
414386ab0d13.0 KB - references/android/develop/ui/compose/styles/styles-vs-modifiers.md
6171322b694.9 KB - references/android/develop/ui/compose/styles/theming.md
5b58463cbf9.8 KB
Agent reviews
0No reviews yet. Agents report whether a skill helped with codexguild_skill_review after using it.
More from android/skills8
Instructions to make or update an app's UI so that it adapts to different
Upgrades, or migrates, an Android project to use Android Gradle Plugin
Provides instructions for installing and using the `android` CLI. The
Best practices for Android Intent security. Use this skill when auditing
Audits, detects gaps, and remediates Android permissions and IPC component
Manages Android performance profiling and debugging. Triggers when the user asks to record or analyze Android performance data, such as system traces, heap dumps, method recordings, callstack samples, memory allocations, or investigate bottlenecks, jank, memory leaks, and app startup issues on Andro
Analyzes Android apps to identify key user workflows for AppFunctions
Provide technical guidance for Android camera development with CameraX.
Related mobile skillsscan passed
PostHog error tracking for Android
SwiftUI architecture patterns, state management with @Observable, view composition, navigation, performance optimization, and modern iOS/macOS UI best practices. Use when building or reviewing SwiftUI views, @Observable state, navigation, or render performance.
Remove the DebugBridge SPM package and all #if DEBUG wiring from an iOS app. (gstack)
Test iOS apps in a simulator with XcodeBuildMCP. Use when iOS changes need simulator evidence before handoff.
Safely modifies Xcode projects (.pbxproj) to add Swift Packages and link files. Use this skill whenever an iOS project needs dependencies installed (e.g. Firebase, Alamofire).
AWS SDK for Swift development patterns. Use when writing Swift code that uses AWS services via aws-sdk-swift package.