Generate Jetpack Compose `@Preview` functions and `PreviewParameterProvider` classes. Use whenever the user wants to add previews to a `@Composable`, set up multi-config previews (light/dark, screen sizes, font scale, locale, dynamic color), or needs a `PreviewParameterProvider` for composables that take complex parameters. Triggers include phrases like "프리뷰 추가", "preview 만들어줘", "@Preview", "PreviewParameterProvider", "다크모드 프리뷰", "multi preview".
npx claudepluginhub kez-lab/android-custom-skillsThis skill uses the workspace's default tool permissions.
Generates production-quality `@Preview` setups for Jetpack Compose.
Searches, retrieves, and installs Agent Skills from prompts.chat registry using MCP tools like search_skills and get_skill. Activates for finding skills, browsing catalogs, or extending Claude.
Searches prompts.chat for AI prompt templates by keyword or category, retrieves by ID with variable handling, and improves prompts via AI. Use for discovering or enhancing prompts.
Checks Next.js compilation errors using a running Turbopack dev server after code edits. Fixes actionable issues before reporting complete. Replaces `next build`.
Generates production-quality @Preview setups for Jetpack Compose.
Activate when the user is working with a @Composable and asks for any of:
PreviewParameterProvider for a composable whose parameters are non-trivial (data classes, sealed UI states, lists).Read project preferences from .claude/android-skills.json at the git repo root:
{
"compose": {
"themeName": "AppTheme",
"themePackage": "com.example.app.ui.theme",
"previewLocation": "co-located",
"defaultMultiPreview": "PreviewLightDark"
}
}
| Field | Values | Notes |
|---|---|---|
themeName | AppTheme, MyAppTheme, … | Composable used to wrap previews. |
themePackage | FQN of the package containing the theme | Used when the preview file needs an import. |
previewLocation | co-located, separate-file | co-located appends to the composable's file; separate-file creates <Name>Preview.kt next to it. Default: co-located. |
defaultMultiPreview | none, PreviewLightDark, DevicePreviews, … | Annotation applied by default unless the user asks for something else. |
compose.themeName exists in the config → use it.grep -rEn 'fun [A-Z][A-Za-z0-9]*Theme\s*\(' --include='*.kt' app/src/main/java
Filter to files under ui/theme/, theme/, or presentation/theme/. The function whose body invokes MaterialTheme is the project theme.MaterialTheme and warn the user. Do not write to the config.If .claude/android-skills.json is missing or has no compose.themeName AND theme resolution step 2 found nothing, ask the user:
AppTheme)."com.example.app.ui.theme)"Save to .claude/android-skills.json (merge with existing config). Mention the file is committable so the team shares the convention.
MaterialTheme only when nothing exists.@Preview and prefix the function name with Preview (e.g. PreviewLoginScreen).showBackground = true on the base preview so the surface is visible.androidx.compose.ui.tooling.preview when available (@PreviewLightDark, @PreviewScreenSizes, @PreviewFontScale, @PreviewDynamicColors). Only define a custom multi-preview annotation when the user asks for a combination not covered by the built-ins.PreviewParameterProvider<T> next to the preview rather than hard-coding sample data inline. Use sequenceOf(...) for the values property.UiState sealed class or similar, read the actual definition from the codebase before fabricating sample values.@Preview(showBackground = true)
@Composable
private fun PreviewGreeting() {
AppTheme {
Greeting(name = "Android")
}
}
Use the built-in annotation — do not roll your own:
@PreviewLightDark
@Composable
private fun PreviewGreeting() {
AppTheme {
Surface { Greeting(name = "Android") }
}
}
@PreviewLightDark already sets uiMode for both modes; wrapping with Surface ensures the theme background renders.
@PreviewScreenSizes
@PreviewFontScale
@Composable
private fun PreviewLoginScreen() {
AppTheme {
LoginScreen(state = LoginUiState.Idle, onSubmit = {})
}
}
Only create this when the built-ins do not cover the combination the user wants. Place it in ui/preview/Previews.kt:
@Preview(name = "Phone", device = "spec:width=411dp,height=891dp")
@Preview(name = "Foldable", device = "spec:width=673dp,height=841dp")
@Preview(name = "Tablet", device = "spec:width=1280dp,height=800dp")
annotation class DevicePreviews
Then apply: @DevicePreviews on the preview function.
For composables that take a state object, generate a provider rather than crafting sample data inline:
class LoginUiStateProvider : PreviewParameterProvider<LoginUiState> {
override val values: Sequence<LoginUiState> = sequenceOf(
LoginUiState.Idle,
LoginUiState.Loading,
LoginUiState.Error(message = "Invalid credentials"),
LoginUiState.Success(userId = "u_123"),
)
}
@PreviewLightDark
@Composable
private fun PreviewLoginScreen(
@PreviewParameter(LoginUiStateProvider::class) state: LoginUiState,
) {
AppTheme {
Surface { LoginScreen(state = state, onSubmit = {}) }
}
}
@Preview(name = "ko", locale = "ko")
@Preview(name = "en", locale = "en")
@Composable
private fun PreviewWelcome() {
AppTheme { WelcomeScreen() }
}
If the project does not already have them, add via the version catalog:
# libs.versions.toml
[libraries]
androidx-compose-ui-tooling-preview = { group = "androidx.compose.ui", name = "ui-tooling-preview" }
androidx-compose-ui-tooling = { group = "androidx.compose.ui", name = "ui-tooling" }
// app/build.gradle.kts
dependencies {
implementation(libs.androidx.compose.ui.tooling.preview)
debugImplementation(libs.androidx.compose.ui.tooling)
}
ui-tooling must be debugImplementation only — shipping it in release bloats the APK and exposes preview infrastructure.
git rev-parse --show-toplevel to find the repo root, then read <root>/.claude/android-skills.json.UiState types it consumes.compose.defaultMultiPreview from config).compose.previewLocation:
co-located (default) → append to the composable's file, below the composable.separate-file → create <ComposableName>Preview.kt in the same directory.ui-tooling / ui-tooling-preview are missing from dependencies, add them..claude/android-skills.json.ui-tooling in implementation instead of debugImplementation.ViewModel() from inside a @Preview — previews must not depend on DI or runtime state. Pass UI state directly.PreviewParameterProvider instead.@PreviewLightDark etc. by hand when the official annotation already exists.