reis-mobile 0.3.6 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude-plugin/marketplace.json +2 -2
- package/.claude-plugin/plugin.json +1 -1
- package/CHANGELOG.md +24 -0
- package/README.md +175 -168
- package/THIRD_PARTY_NOTICES.md +224 -4
- package/agents/android-architect.md +89 -0
- package/agents/android-performance-engineer.md +92 -0
- package/agents/android-test-engineer.md +97 -0
- package/agents/flutter-test-engineer.md +2 -0
- package/agents/ios-architect.md +93 -0
- package/agents/ios-performance-engineer.md +92 -0
- package/agents/ios-test-engineer.md +95 -0
- package/agents/lead-mobile.md +10 -1
- package/agents/mobile-staff-engineer.md +1 -1
- package/agents/rn-architect.md +94 -0
- package/agents/rn-performance-engineer.md +92 -0
- package/agents/rn-test-engineer.md +98 -0
- package/bin/reis-mobile.mjs +59 -17
- package/commands/debate.md +10 -1
- package/commands/debug.md +60 -0
- package/commands/reis-mobile.md +7 -2
- package/core/config/project.mjs +59 -0
- package/core/registry/frontmatter.mjs +15 -4
- package/core/registry/registry.mjs +21 -1
- package/core/router/intents.mjs +2 -0
- package/core/router/router.mjs +10 -5
- package/package.json +1 -1
- package/skills/android-adaptive/SKILL.md +304 -0
- package/skills/android-adaptive/references/android/develop/ui/compose/layouts/adaptive/flexbox/container-behavior.md +112 -0
- package/skills/android-adaptive/references/android/develop/ui/compose/layouts/adaptive/flexbox/get-started.md +69 -0
- package/skills/android-adaptive/references/android/develop/ui/compose/layouts/adaptive/flexbox/index.md +81 -0
- package/skills/android-adaptive/references/android/develop/ui/compose/layouts/adaptive/flexbox/item-behavior.md +170 -0
- package/skills/android-adaptive/references/android/develop/ui/compose/layouts/adaptive/grid/container-properties.md +415 -0
- package/skills/android-adaptive/references/android/develop/ui/compose/layouts/adaptive/grid/get-started.md +51 -0
- package/skills/android-adaptive/references/android/develop/ui/compose/layouts/adaptive/grid/index.md +73 -0
- package/skills/android-adaptive/references/android/develop/ui/compose/layouts/adaptive/grid/item-properties.md +170 -0
- package/skills/android-adaptive/references/android/develop/ui/compose/layouts/adaptive/mediaquery/index.md +333 -0
- package/skills/android-adaptive/references/android/develop/ui/compose/tooling/debug.md +114 -0
- package/skills/android-adaptive/references/android/guide/navigation/navigation-3/recipes/material-listdetail.md +141 -0
- package/skills/android-agp-9-upgrade/SKILL.md +106 -0
- package/skills/android-agp-9-upgrade/references/android/build/migrate-to-built-in-kotlin.md +416 -0
- package/skills/android-agp-9-upgrade/references/android/build/releases/agp-9-0-0-release-notes.md +554 -0
- package/skills/android-agp-9-upgrade/references/buildconfig.md +54 -0
- package/skills/android-agp-9-upgrade/references/ksp-kapt.md +39 -0
- package/skills/android-agp-9-upgrade/references/paparazzi-gradle-9.md +30 -0
- package/skills/android-agp-9-upgrade/references/recipes.md +62 -0
- package/skills/android-appfunctions/SKILL.md +74 -0
- package/skills/android-appfunctions/references/adb-interaction-testing.md +95 -0
- package/skills/android-appfunctions/references/context.md +26 -0
- package/skills/android-appfunctions/references/feature-discovery-analysis.md +71 -0
- package/skills/android-appfunctions/references/implementation-configuration.md +282 -0
- package/skills/android-appfunctions/references/kdoc-refinement-optimization.md +75 -0
- package/skills/android-appfunctions/references/migrate-to-service-entry-point.md +226 -0
- package/skills/android-camerax/SKILL.md +135 -0
- package/skills/android-camerax/references/camera1-to-camerax.md +198 -0
- package/skills/android-camerax/references/camera2-to-camerax.md +193 -0
- package/skills/android-camerax/references/expert-blueprints.md +58 -0
- package/skills/android-camerax/references/foldables.md +83 -0
- package/skills/android-camerax/references/immutability.md +60 -0
- package/skills/android-camerax/references/low-light.md +124 -0
- package/skills/android-camerax/references/mlkit-spatial.md +75 -0
- package/skills/android-camerax/references/modern-apis.md +42 -0
- package/skills/android-camerax/references/testing.md +69 -0
- package/skills/android-camerax/references/thermals.md +85 -0
- package/skills/android-camerax/references/wear-os.md +76 -0
- package/skills/android-camerax/references/xr.md +54 -0
- package/skills/android-cli/SKILL.md +474 -0
- package/skills/android-cli/references/interact.md +113 -0
- package/skills/android-cli/references/journeys.md +120 -0
- package/skills/android-code-review/SKILL.md +58 -0
- package/skills/android-display-glasses-with-jetpack-compose-glimmer/SKILL.md +340 -0
- package/skills/android-display-glasses-with-jetpack-compose-glimmer/references/android/design/ui/ai-glasses/guides/interaction/inputs.md +67 -0
- package/skills/android-display-glasses-with-jetpack-compose-glimmer/references/android/develop/xr/jetpack-xr-sdk/access-hardware-projected-context.md +388 -0
- package/skills/android-display-glasses-with-jetpack-compose-glimmer/references/android/develop/xr/jetpack-xr-sdk/jetpack-compose-glimmer/buttons.md +139 -0
- package/skills/android-display-glasses-with-jetpack-compose-glimmer/references/android/develop/xr/jetpack-xr-sdk/jetpack-compose-glimmer/cards.md +148 -0
- package/skills/android-display-glasses-with-jetpack-compose-glimmer/references/android/develop/xr/jetpack-xr-sdk/jetpack-compose-glimmer/focus.md +107 -0
- package/skills/android-display-glasses-with-jetpack-compose-glimmer/references/android/develop/xr/jetpack-xr-sdk/jetpack-compose-glimmer/icons.md +90 -0
- package/skills/android-display-glasses-with-jetpack-compose-glimmer/references/android/develop/xr/jetpack-xr-sdk/jetpack-compose-glimmer/text.md +69 -0
- package/skills/android-display-glasses-with-jetpack-compose-glimmer/references/android/develop/xr/jetpack-xr-sdk/jetpack-compose-glimmer/title-chips.md +82 -0
- package/skills/android-display-glasses-with-jetpack-compose-glimmer/references/android/develop/xr/jetpack-xr-sdk/request-hardware-permissions.md +213 -0
- package/skills/android-display-glasses-with-jetpack-compose-glimmer/references/button-samples-source.md +176 -0
- package/skills/android-display-glasses-with-jetpack-compose-glimmer/references/button-source.md +203 -0
- package/skills/android-display-glasses-with-jetpack-compose-glimmer/references/card-samples-source.md +296 -0
- package/skills/android-display-glasses-with-jetpack-compose-glimmer/references/card-source.md +515 -0
- package/skills/android-display-glasses-with-jetpack-compose-glimmer/references/deptheffect-source.md +224 -0
- package/skills/android-display-glasses-with-jetpack-compose-glimmer/references/deptheffectlevels-source.md +105 -0
- package/skills/android-display-glasses-with-jetpack-compose-glimmer/references/glimmersansflextypography-source.md +270 -0
- package/skills/android-display-glasses-with-jetpack-compose-glimmer/references/glimmertheme-source.md +182 -0
- package/skills/android-display-glasses-with-jetpack-compose-glimmer/references/icon-source.md +388 -0
- package/skills/android-display-glasses-with-jetpack-compose-glimmer/references/iconbutton-source.md +126 -0
- package/skills/android-display-glasses-with-jetpack-compose-glimmer/references/iconsizes-source.md +78 -0
- package/skills/android-display-glasses-with-jetpack-compose-glimmer/references/list-source.md +27 -0
- package/skills/android-display-glasses-with-jetpack-compose-glimmer/references/listitem-source.md +272 -0
- package/skills/android-display-glasses-with-jetpack-compose-glimmer/references/liststate-source.md +427 -0
- package/skills/android-display-glasses-with-jetpack-compose-glimmer/references/material-hct-source.md +217 -0
- package/skills/android-display-glasses-with-jetpack-compose-glimmer/references/projectedcontext-source.md +265 -0
- package/skills/android-display-glasses-with-jetpack-compose-glimmer/references/stack-source.md +368 -0
- package/skills/android-display-glasses-with-jetpack-compose-glimmer/references/stackitemscope-source.md +440 -0
- package/skills/android-display-glasses-with-jetpack-compose-glimmer/references/stackstate-source.md +325 -0
- package/skills/android-display-glasses-with-jetpack-compose-glimmer/references/surface-source.md +1211 -0
- package/skills/android-display-glasses-with-jetpack-compose-glimmer/references/titlechip-samples-source.md +101 -0
- package/skills/android-display-glasses-with-jetpack-compose-glimmer/references/titlechip-source.md +131 -0
- package/skills/android-edge-to-edge/SKILL.md +429 -0
- package/skills/android-engage-sdk-integration/SKILL.md +130 -0
- package/skills/android-engage-sdk-integration/references/android/guide/playcore/engage/faq.md +439 -0
- package/skills/android-engage-sdk-integration/references/android/guide/playcore/engage/food.md +1149 -0
- package/skills/android-engage-sdk-integration/references/android/guide/playcore/engage/healthandfitness.md +1055 -0
- package/skills/android-engage-sdk-integration/references/android/guide/playcore/engage/listen.md +1050 -0
- package/skills/android-engage-sdk-integration/references/android/guide/playcore/engage/otherverticals.md +1301 -0
- package/skills/android-engage-sdk-integration/references/android/guide/playcore/engage/read.md +910 -0
- package/skills/android-engage-sdk-integration/references/android/guide/playcore/engage/shopping.md +1224 -0
- package/skills/android-engage-sdk-integration/references/android/guide/playcore/engage/social.md +719 -0
- package/skills/android-engage-sdk-integration/references/android/guide/playcore/engage/travel.md +1413 -0
- package/skills/android-engage-sdk-integration/references/android/guide/playcore/engage/tv/continue-watching/index.md +19 -0
- package/skills/android-engage-sdk-integration/references/android/guide/playcore/engage/tv/entitlements.md +353 -0
- package/skills/android-engage-sdk-integration/references/android/guide/playcore/engage/tv/getting-started.md +202 -0
- package/skills/android-engage-sdk-integration/references/android/guide/playcore/engage/tv/recommendations.md +471 -0
- package/skills/android-engage-sdk-integration/references/android/guide/playcore/engage/watch.md +1081 -0
- package/skills/android-engage-sdk-integration/references/clusters.md +154 -0
- package/skills/android-engage-sdk-integration/references/common.md +519 -0
- package/skills/android-engage-sdk-integration/references/patterns.md +527 -0
- package/skills/android-engage-sdk-integration/references/requests.md +260 -0
- package/skills/android-engage-sdk-integration/references/schemas/food.md +509 -0
- package/skills/android-engage-sdk-integration/references/schemas/listen.md +842 -0
- package/skills/android-engage-sdk-integration/references/schemas/other.md +220 -0
- package/skills/android-engage-sdk-integration/references/schemas/read.md +412 -0
- package/skills/android-engage-sdk-integration/references/schemas/shopping.md +357 -0
- package/skills/android-engage-sdk-integration/references/schemas/social.md +228 -0
- package/skills/android-engage-sdk-integration/references/schemas/travel.md +923 -0
- package/skills/android-engage-sdk-integration/references/schemas/tv.md +1226 -0
- package/skills/android-engage-sdk-integration/references/schemas/watch.md +1137 -0
- package/skills/android-engage-sdk-integration/references/troubleshooting.md +39 -0
- package/skills/android-gradle-build-debug/SKILL.md +71 -0
- package/skills/android-intent-security/SKILL.md +550 -0
- package/skills/android-leanback-to-compose-tv-migration/SKILL.md +743 -0
- package/skills/android-leanback-to-compose-tv-migration/references/android/training/tv/get-started/navigation.md +372 -0
- package/skills/android-leanback-to-compose-tv-migration/references/android/training/tv/playback/compose/browse.md +243 -0
- package/skills/android-leanback-to-compose-tv-migration/references/android/training/tv/playback/compose/index.md +153 -0
- package/skills/android-media3-cast-integration/SKILL.md +236 -0
- package/skills/android-media3-cast-integration/references/android/media/media3/cast/create-castplayer.md +390 -0
- package/skills/android-media3-cast-integration/references/android/media/media3/cast/customize-castoptions.md +93 -0
- package/skills/android-media3-cast-integration/references/android/media/media3/cast/index.md +21 -0
- package/skills/android-migrate-xml-views-to-jetpack-compose/SKILL.md +127 -0
- package/skills/android-migrate-xml-views-to-jetpack-compose/references/analysis-of-the-project-and-layout.md +42 -0
- package/skills/android-migrate-xml-views-to-jetpack-compose/references/android/develop/ui/compose/designsystems/migrate-xml-theme-to-compose.md +171 -0
- package/skills/android-migrate-xml-views-to-jetpack-compose/references/android/develop/ui/compose/migrate/interoperability-apis/compose-in-views.md +299 -0
- package/skills/android-migrate-xml-views-to-jetpack-compose/references/android/develop/ui/compose/migrate/interoperability-apis/views-in-compose.md +286 -0
- package/skills/android-migrate-xml-views-to-jetpack-compose/references/android/develop/ui/compose/setup-compose-dependencies-and-compiler.md +197 -0
- package/skills/android-migrate-xml-views-to-jetpack-compose/references/identify-optimal-xml-candidate.md +31 -0
- package/skills/android-migrate-xml-views-to-jetpack-compose/references/xml-layout-migration.md +86 -0
- package/skills/android-ml-kit-genai-prompt-api/SKILL.md +124 -0
- package/skills/android-ml-kit-genai-prompt-api/references/get-started.md +272 -0
- package/skills/android-ml-kit-genai-prompt-api/references/prefix-caching.md +146 -0
- package/skills/android-ml-kit-genai-prompt-api/references/prompt-design.md +55 -0
- package/skills/android-ml-kit-genai-prompt-api/references/prompt-optimization.md +74 -0
- package/skills/android-ml-kit-genai-prompt-api/references/structured-output.md +219 -0
- package/skills/android-ml-kit-genai-prompt-api/references/system-instructions.md +71 -0
- package/skills/android-navigation-3/SKILL.md +122 -0
- package/skills/android-navigation-3/references/android/guide/navigation/navigation-3/index.md +51 -0
- package/skills/android-navigation-3/references/android/guide/navigation/navigation-3/migration-guide.md +670 -0
- package/skills/android-navigation-3/references/android/guide/navigation/navigation-3/recipes/animations.md +147 -0
- package/skills/android-navigation-3/references/android/guide/navigation/navigation-3/recipes/basic.md +89 -0
- package/skills/android-navigation-3/references/android/guide/navigation/navigation-3/recipes/basicdsl.md +85 -0
- package/skills/android-navigation-3/references/android/guide/navigation/navigation-3/recipes/basicsaveable.md +90 -0
- package/skills/android-navigation-3/references/android/guide/navigation/navigation-3/recipes/bottomsheet.md +195 -0
- package/skills/android-navigation-3/references/android/guide/navigation/navigation-3/recipes/common-ui.md +200 -0
- package/skills/android-navigation-3/references/android/guide/navigation/navigation-3/recipes/conditional-transitions.md +182 -0
- package/skills/android-navigation-3/references/android/guide/navigation/navigation-3/recipes/conditional.md +230 -0
- package/skills/android-navigation-3/references/android/guide/navigation/navigation-3/recipes/deeplinks-custommatcher.md +176 -0
- package/skills/android-navigation-3/references/android/guide/navigation/navigation-3/recipes/deeplinks-staticuri.md +140 -0
- package/skills/android-navigation-3/references/android/guide/navigation/navigation-3/recipes/deeplinks-syntheticbackstack.md +184 -0
- package/skills/android-navigation-3/references/android/guide/navigation/navigation-3/recipes/dialog.md +107 -0
- package/skills/android-navigation-3/references/android/guide/navigation/navigation-3/recipes/lifecycle-owner.md +185 -0
- package/skills/android-navigation-3/references/android/guide/navigation/navigation-3/recipes/material-listdetail.md +141 -0
- package/skills/android-navigation-3/references/android/guide/navigation/navigation-3/recipes/material-supportingpane.md +145 -0
- package/skills/android-navigation-3/references/android/guide/navigation/navigation-3/recipes/modular-hilt.md +283 -0
- package/skills/android-navigation-3/references/android/guide/navigation/navigation-3/recipes/modular-koin.md +287 -0
- package/skills/android-navigation-3/references/android/guide/navigation/navigation-3/recipes/multiple-backstacks.md +468 -0
- package/skills/android-navigation-3/references/android/guide/navigation/navigation-3/recipes/passingarguments.md +371 -0
- package/skills/android-navigation-3/references/android/guide/navigation/navigation-3/recipes/results-event.md +273 -0
- package/skills/android-navigation-3/references/android/guide/navigation/navigation-3/recipes/results-state.md +266 -0
- package/skills/android-navigation-3/references/android/guide/navigation/navigation-3/recipes/scenes-listdetail.md +435 -0
- package/skills/android-navigation-3/references/android/guide/navigation/navigation-3/recipes/scenes-twopane.md +244 -0
- package/skills/android-navigation-3/references/android/guide/navigation/type-safe-destinations.md +129 -0
- package/skills/android-navigation-event/SKILL.md +312 -0
- package/skills/android-navigation-event/references/android/guide/navigation/navigation-event/dispatcher.md +134 -0
- package/skills/android-navigation-event/references/android/guide/navigation/navigation-event/handle-back.md +217 -0
- package/skills/android-navigation-event/references/android/guide/navigation/navigation-event/index.md +83 -0
- package/skills/android-navigation-event/references/android/guide/navigation/navigation-event/setup.md +32 -0
- package/skills/android-play-billing-library-version-upgrade/SKILL.md +96 -0
- package/skills/android-play-billing-library-version-upgrade/references/android/google/play/billing/release-notes.md +1240 -0
- package/skills/android-play-billing-library-version-upgrade/references/migration-logic.md +78 -0
- package/skills/android-play-billing-library-version-upgrade/references/version-checklist.md +54 -0
- package/skills/android-play-policy-insights/SKILL.md +172 -0
- package/skills/android-play-policy-insights/resources/common_mandates.md +100 -0
- package/skills/android-play-policy-insights/resources/compliance_report_template.md +59 -0
- package/skills/android-play-policy-insights/resources/critic.md +86 -0
- package/skills/android-play-policy-insights/resources/goal_data_safety.md +212 -0
- package/skills/android-play-policy-insights/resources/goal_permissions_and_apis.md +459 -0
- package/skills/android-play-policy-insights/resources/goal_user_account.md +106 -0
- package/skills/android-play-policy-insights/resources/policies.json +321 -0
- package/skills/android-play-policy-insights/resources/scanner_config.json +843 -0
- package/skills/android-play-policy-insights/scripts/generate_report.py +860 -0
- package/skills/android-play-policy-insights/scripts/orchestrator.py +1313 -0
- package/skills/android-play-policy-insights/scripts/play_store_scraper.py +410 -0
- package/skills/android-play-policy-insights/scripts/scanner.py +261 -0
- package/skills/android-play-policy-insights/scripts/template_engine.py +243 -0
- package/skills/android-profiler/SKILL.md +60 -0
- package/skills/android-profiler/analysis/analysis_orchestrator.md +32 -0
- package/skills/android-profiler/analysis/workflows/perfetto-sql/perfetto_sql.md +28 -0
- package/skills/android-profiler/analysis/workflows/perfetto-trace-analysis/perfetto_trace_analysis.md +121 -0
- package/skills/android-profiler/analysis/workflows/perfetto-trace-analysis/references/guiding_principles.md +51 -0
- package/skills/android-profiler/analysis/workflows/perfetto-trace-analysis/references/hints/domain_hints_template.md +7 -0
- package/skills/android-profiler/analysis/workflows/perfetto-trace-analysis/references/hints/subsystems/hints_cpu.md +56 -0
- package/skills/android-profiler/analysis/workflows/perfetto-trace-analysis/references/hints/subsystems/hints_graphics.md +51 -0
- package/skills/android-profiler/analysis/workflows/perfetto-trace-analysis/references/hints/subsystems/hints_io.md +46 -0
- package/skills/android-profiler/analysis/workflows/perfetto-trace-analysis/references/hints/subsystems/hints_ipc.md +41 -0
- package/skills/android-profiler/analysis/workflows/perfetto-trace-analysis/references/hints/subsystems/hints_memory.md +55 -0
- package/skills/android-profiler/analysis/workflows/perfetto-trace-analysis/references/hints/subsystems/hints_power.md +33 -0
- package/skills/android-profiler/analysis/workflows/perfetto-trace-analysis/references/per_candidate_analysis.md +172 -0
- package/skills/android-profiler/analysis/workflows/perfetto-trace-analysis/references/triage.md +94 -0
- package/skills/android-profiler/recording/recording_orchestrator.md +36 -0
- package/skills/android-profiler/recording/workflows/perfetto-trace-recording/perfetto_trace_recording.md +148 -0
- package/skills/android-profiler/recording/workflows/perfetto-trace-recording/references/example-configs/app_jank.pftxt +43 -0
- package/skills/android-profiler/recording/workflows/perfetto-trace-recording/references/example-configs/cpu_profile.pftxt +35 -0
- package/skills/android-profiler/recording/workflows/perfetto-trace-recording/references/example-configs/java_heap_dump.pftxt +21 -0
- package/skills/android-profiler/recording/workflows/perfetto-trace-recording/references/example-configs/long_background.pftxt +37 -0
- package/skills/android-profiler/recording/workflows/perfetto-trace-recording/references/example-configs/memory_counters.pftxt +45 -0
- package/skills/android-profiler/recording/workflows/perfetto-trace-recording/references/example-configs/native_heap.pftxt +21 -0
- package/skills/android-profiler/recording/workflows/perfetto-trace-recording/references/example-configs/sched_cpu.pftxt +33 -0
- package/skills/android-profiler/recording/workflows/perfetto-trace-recording/references/trace_config_reference.md +102 -0
- package/skills/android-profiler/references/env_setup.md +15 -0
- package/skills/android-profiler/references/perfetto/setup.md +29 -0
- package/skills/android-profiler/references/perfetto/sql.md +327 -0
- package/skills/android-r8-analyzer/SKILL.md +72 -0
- package/skills/android-r8-analyzer/references/CONFIGURATION-ANALYZER.md +287 -0
- package/skills/android-r8-analyzer/references/CONFIGURATION.md +44 -0
- package/skills/android-r8-analyzer/references/KEEP-RULES-IMPACT-HIERARCHY.md +83 -0
- package/skills/android-r8-analyzer/references/REDUNDANT-RULES.md +222 -0
- package/skills/android-r8-analyzer/references/REFLECTION-GUIDE.md +139 -0
- package/skills/android-r8-analyzer/references/REPORT_FORMAT.md +51 -0
- package/skills/android-r8-analyzer/references/android/topic/performance/app-optimization/enable-app-optimization.md +252 -0
- package/skills/android-r8-analyzer/references/android/training/testing/other-components/ui-automator.md +312 -0
- package/skills/android-restore-credentials/SKILL.md +359 -0
- package/skills/android-restore-credentials/references/android/guide/topics/manifest/application-element.md +832 -0
- package/skills/android-restore-credentials/references/android/identity/passkeys/create-passkeys.md +327 -0
- package/skills/android-restore-credentials/references/android/identity/passkeys/sign-in-with-passkeys.md +219 -0
- package/skills/android-styles/SKILL.md +229 -0
- package/skills/android-styles/references/android/develop/ui/compose/designsystems/custom.md +459 -0
- package/skills/android-styles/references/android/develop/ui/compose/styles/fundamentals.md +421 -0
- package/skills/android-styles/references/android/develop/ui/compose/styles/state-animations.md +461 -0
- package/skills/android-styles/references/android/develop/ui/compose/styles/styles-vs-modifiers.md +48 -0
- package/skills/android-styles/references/android/develop/ui/compose/styles/theming.md +269 -0
- package/skills/android-verified-email/SKILL.md +432 -0
- package/skills/android-verified-email/references/android/identity/credential-manager/index.md +67 -0
- package/skills/android-verified-email/references/android/identity/digital-credentials/credential-verifier.md +166 -0
- package/skills/android-verified-email/references/android/identity/digital-credentials/email-verification-implementation.md +313 -0
- package/skills/android-verified-email/references/android/identity/digital-credentials/email-verification.md +158 -0
- package/skills/android-verified-email/references/android/identity/digital-credentials/index.md +112 -0
- package/skills/android-verified-email/references/android/identity/passkeys/create-passkeys.md +327 -0
- package/skills/android-verified-email/references/android/identity/sign-in/credential-manager-webview.md +84 -0
- package/skills/android-wear-compose-m3/SKILL.md +365 -0
- package/skills/android-wear-compose-m3/references/android/training/wearables/compose/migrate-to-material3.md +677 -0
- package/skills/android-wear-compose-m3/references/foundation/AmbientModeSample.kt.md +123 -0
- package/skills/android-wear-compose-m3/references/foundation/AmbientModeSample.kt.md.txt +123 -0
- package/skills/android-wear-compose-m3/references/foundation/CurvedWorldSample.kt.md +430 -0
- package/skills/android-wear-compose-m3/references/foundation/CurvedWorldSample.kt.md.txt +430 -0
- package/skills/android-wear-compose-m3/references/foundation/ExpandableSample.kt.md +99 -0
- package/skills/android-wear-compose-m3/references/foundation/ExpandableSample.kt.md.txt +99 -0
- package/skills/android-wear-compose-m3/references/foundation/HierarchicalFocusSample.kt.md +141 -0
- package/skills/android-wear-compose-m3/references/foundation/HierarchicalFocusSample.kt.md.txt +141 -0
- package/skills/android-wear-compose-m3/references/foundation/PagerSamples.kt.md +56 -0
- package/skills/android-wear-compose-m3/references/foundation/PagerSamples.kt.md.txt +56 -0
- package/skills/android-wear-compose-m3/references/foundation/RotarySamples.kt.md +153 -0
- package/skills/android-wear-compose-m3/references/foundation/RotarySamples.kt.md.txt +153 -0
- package/skills/android-wear-compose-m3/references/foundation/ScalingLazyColumnSample.kt.md +131 -0
- package/skills/android-wear-compose-m3/references/foundation/ScalingLazyColumnSample.kt.md.txt +131 -0
- package/skills/android-wear-compose-m3/references/foundation/SwipeToDismissBoxSample.kt.md +169 -0
- package/skills/android-wear-compose-m3/references/foundation/SwipeToDismissBoxSample.kt.md.txt +169 -0
- package/skills/android-wear-compose-m3/references/foundation/SwipeToRevealSample.kt.md +282 -0
- package/skills/android-wear-compose-m3/references/foundation/SwipeToRevealSample.kt.md.txt +282 -0
- package/skills/android-wear-compose-m3/references/foundation/TransformingLazyColumnSample.kt.md +335 -0
- package/skills/android-wear-compose-m3/references/foundation/TransformingLazyColumnSample.kt.md.txt +335 -0
- package/skills/android-wear-compose-m3/references/material3/AlertDialogSample.kt.md +377 -0
- package/skills/android-wear-compose-m3/references/material3/AlertDialogSample.kt.md.txt +377 -0
- package/skills/android-wear-compose-m3/references/material3/AnimatedTextSample.kt.md +165 -0
- package/skills/android-wear-compose-m3/references/material3/AnimatedTextSample.kt.md.txt +165 -0
- package/skills/android-wear-compose-m3/references/material3/ButtonGroupSample.kt.md +91 -0
- package/skills/android-wear-compose-m3/references/material3/ButtonGroupSample.kt.md.txt +91 -0
- package/skills/android-wear-compose-m3/references/material3/ButtonSample.kt.md +496 -0
- package/skills/android-wear-compose-m3/references/material3/ButtonSample.kt.md.txt +496 -0
- package/skills/android-wear-compose-m3/references/material3/CardSample.kt.md +470 -0
- package/skills/android-wear-compose-m3/references/material3/CardSample.kt.md.txt +470 -0
- package/skills/android-wear-compose-m3/references/material3/CheckboxButtonSample.kt.md +67 -0
- package/skills/android-wear-compose-m3/references/material3/CheckboxButtonSample.kt.md.txt +67 -0
- package/skills/android-wear-compose-m3/references/material3/ConfirmationDialogSample.kt.md +162 -0
- package/skills/android-wear-compose-m3/references/material3/ConfirmationDialogSample.kt.md.txt +162 -0
- package/skills/android-wear-compose-m3/references/material3/CurvedTextSamples.kt.md +78 -0
- package/skills/android-wear-compose-m3/references/material3/CurvedTextSamples.kt.md.txt +78 -0
- package/skills/android-wear-compose-m3/references/material3/DatePickerSample.kt.md +131 -0
- package/skills/android-wear-compose-m3/references/material3/DatePickerSample.kt.md.txt +131 -0
- package/skills/android-wear-compose-m3/references/material3/DynamicColorSchemeSample.kt.md +74 -0
- package/skills/android-wear-compose-m3/references/material3/DynamicColorSchemeSample.kt.md.txt +74 -0
- package/skills/android-wear-compose-m3/references/material3/EdgeButtonSample.kt.md +63 -0
- package/skills/android-wear-compose-m3/references/material3/EdgeButtonSample.kt.md.txt +63 -0
- package/skills/android-wear-compose-m3/references/material3/FadingExpandingLabelSample.kt.md +60 -0
- package/skills/android-wear-compose-m3/references/material3/FadingExpandingLabelSample.kt.md.txt +60 -0
- package/skills/android-wear-compose-m3/references/material3/IconButtonSample.kt.md +125 -0
- package/skills/android-wear-compose-m3/references/material3/IconButtonSample.kt.md.txt +125 -0
- package/skills/android-wear-compose-m3/references/material3/IconToggleButtonSample.kt.md +116 -0
- package/skills/android-wear-compose-m3/references/material3/IconToggleButtonSample.kt.md.txt +116 -0
- package/skills/android-wear-compose-m3/references/material3/LevelIndicatorSample.kt.md +68 -0
- package/skills/android-wear-compose-m3/references/material3/LevelIndicatorSample.kt.md.txt +68 -0
- package/skills/android-wear-compose-m3/references/material3/LinearProgressIndicatorSample.kt.md +50 -0
- package/skills/android-wear-compose-m3/references/material3/LinearProgressIndicatorSample.kt.md.txt +50 -0
- package/skills/android-wear-compose-m3/references/material3/ListHeaderSample.kt.md +177 -0
- package/skills/android-wear-compose-m3/references/material3/ListHeaderSample.kt.md.txt +177 -0
- package/skills/android-wear-compose-m3/references/material3/OneHandedGestureSamples.kt.md +651 -0
- package/skills/android-wear-compose-m3/references/material3/OneHandedGestureSamples.kt.md.txt +651 -0
- package/skills/android-wear-compose-m3/references/material3/OpenOnPhoneDialogSample.kt.md +57 -0
- package/skills/android-wear-compose-m3/references/material3/OpenOnPhoneDialogSample.kt.md.txt +57 -0
- package/skills/android-wear-compose-m3/references/material3/PageIndicatorSample.kt.md +110 -0
- package/skills/android-wear-compose-m3/references/material3/PageIndicatorSample.kt.md.txt +110 -0
- package/skills/android-wear-compose-m3/references/material3/PagerScaffoldSample.kt.md +204 -0
- package/skills/android-wear-compose-m3/references/material3/PagerScaffoldSample.kt.md.txt +204 -0
- package/skills/android-wear-compose-m3/references/material3/PickerGroupSample.kt.md +139 -0
- package/skills/android-wear-compose-m3/references/material3/PickerGroupSample.kt.md.txt +139 -0
- package/skills/android-wear-compose-m3/references/material3/PickerSample.kt.md +111 -0
- package/skills/android-wear-compose-m3/references/material3/PickerSample.kt.md.txt +111 -0
- package/skills/android-wear-compose-m3/references/material3/PlaceholderSample.kt.md +184 -0
- package/skills/android-wear-compose-m3/references/material3/PlaceholderSample.kt.md.txt +184 -0
- package/skills/android-wear-compose-m3/references/material3/ProgressIndicatorSample.kt.md +263 -0
- package/skills/android-wear-compose-m3/references/material3/ProgressIndicatorSample.kt.md.txt +263 -0
- package/skills/android-wear-compose-m3/references/material3/RadioButtonSample.kt.md +105 -0
- package/skills/android-wear-compose-m3/references/material3/RadioButtonSample.kt.md.txt +105 -0
- package/skills/android-wear-compose-m3/references/material3/ScaffoldSample.kt.md +146 -0
- package/skills/android-wear-compose-m3/references/material3/ScaffoldSample.kt.md.txt +146 -0
- package/skills/android-wear-compose-m3/references/material3/ScrollAwaySample.kt.md +97 -0
- package/skills/android-wear-compose-m3/references/material3/ScrollAwaySample.kt.md.txt +97 -0
- package/skills/android-wear-compose-m3/references/material3/ScrollIndicatorSample.kt.md +66 -0
- package/skills/android-wear-compose-m3/references/material3/ScrollIndicatorSample.kt.md.txt +66 -0
- package/skills/android-wear-compose-m3/references/material3/SliderSample.kt.md +86 -0
- package/skills/android-wear-compose-m3/references/material3/SliderSample.kt.md.txt +86 -0
- package/skills/android-wear-compose-m3/references/material3/StepperSample.kt.md +148 -0
- package/skills/android-wear-compose-m3/references/material3/StepperSample.kt.md.txt +148 -0
- package/skills/android-wear-compose-m3/references/material3/SurfaceTransformationSample.kt.md +166 -0
- package/skills/android-wear-compose-m3/references/material3/SurfaceTransformationSample.kt.md.txt +166 -0
- package/skills/android-wear-compose-m3/references/material3/SwipeToDismissBoxSample.kt.md +172 -0
- package/skills/android-wear-compose-m3/references/material3/SwipeToDismissBoxSample.kt.md.txt +172 -0
- package/skills/android-wear-compose-m3/references/material3/SwipeToRevealSample.kt.md +367 -0
- package/skills/android-wear-compose-m3/references/material3/SwipeToRevealSample.kt.md.txt +367 -0
- package/skills/android-wear-compose-m3/references/material3/SwitchButtonSample.kt.md +66 -0
- package/skills/android-wear-compose-m3/references/material3/SwitchButtonSample.kt.md.txt +66 -0
- package/skills/android-wear-compose-m3/references/material3/TextButtonSample.kt.md +115 -0
- package/skills/android-wear-compose-m3/references/material3/TextButtonSample.kt.md.txt +115 -0
- package/skills/android-wear-compose-m3/references/material3/TextToggleButtonSample.kt.md +71 -0
- package/skills/android-wear-compose-m3/references/material3/TextToggleButtonSample.kt.md.txt +71 -0
- package/skills/android-wear-compose-m3/references/material3/TimePickerSample.kt.md +151 -0
- package/skills/android-wear-compose-m3/references/material3/TimePickerSample.kt.md.txt +151 -0
- package/skills/android-wear-compose-m3/references/material3/TimeTextSample.kt.md +65 -0
- package/skills/android-wear-compose-m3/references/material3/TimeTextSample.kt.md.txt +65 -0
- package/skills/android-wear-compose-m3/references/material3/TransformationSpecSample.kt.md +246 -0
- package/skills/android-wear-compose-m3/references/material3/TransformationSpecSample.kt.md.txt +246 -0
- package/skills/android-wear-compose-m3/references/material3/TransformingLazyColumnNotificationsSample.kt.md +89 -0
- package/skills/android-wear-compose-m3/references/material3/TransformingLazyColumnNotificationsSample.kt.md.txt +89 -0
- package/skills/android-wear-compose-m3/references/material3/TransformingLazyColumnSample.kt.md +309 -0
- package/skills/android-wear-compose-m3/references/material3/TransformingLazyColumnSample.kt.md.txt +309 -0
- package/skills/android-wear-compose-m3/references/navigation3/SwipeDismissableSceneStrategySample.kt.md +205 -0
- package/skills/android-wear-compose-m3/references/navigation3/SwipeDismissableSceneStrategySample.kt.md.txt +205 -0
- package/skills/{architecture-feature-first → flutter-architecture-feature-first}/SKILL.md +1 -1
- package/skills/{bloc → flutter-bloc}/SKILL.md +1 -1
- package/skills/flutter-build-debug/SKILL.md +66 -0
- package/skills/{code-review → flutter-code-review}/SKILL.md +1 -1
- package/skills/{dart-3-updates → flutter-dart-3-updates}/SKILL.md +1 -1
- package/skills/{dart-fix-runtime-errors → flutter-dart-fix-runtime-errors}/SKILL.md +1 -1
- package/skills/{dart-resolve-package-conflicts → flutter-dart-resolve-package-conflicts}/SKILL.md +1 -1
- package/skills/{dart-run-static-analysis → flutter-dart-run-static-analysis}/SKILL.md +1 -1
- package/skills/{dart-use-pattern-matching → flutter-dart-use-pattern-matching}/SKILL.md +1 -1
- package/skills/{effective-dart → flutter-effective-dart}/SKILL.md +1 -1
- package/skills/{provider → flutter-provider}/SKILL.md +1 -1
- package/skills/{riverpod → flutter-riverpod}/SKILL.md +1 -1
- package/skills/ios-cocoapods-debug/SKILL.md +65 -0
- package/skills/ios-code-review/SKILL.md +56 -0
- package/skills/ios-xcode-build-debug/SKILL.md +66 -0
- package/skills/{detect-mobile-stack → mobile-detect-stack}/SKILL.md +1 -1
- package/skills/mobile-firebase/SKILL.md +54 -0
- package/skills/mobile-firebase/references/android/ai-logic.md +31 -0
- package/skills/mobile-firebase/references/android/analytics.md +33 -0
- package/skills/mobile-firebase/references/android/app-check.md +36 -0
- package/skills/mobile-firebase/references/android/auth.md +44 -0
- package/skills/mobile-firebase/references/android/crashlytics.md +31 -0
- package/skills/mobile-firebase/references/android/firestore.md +44 -0
- package/skills/mobile-firebase/references/android/functions.md +33 -0
- package/skills/mobile-firebase/references/android/in-app-messaging.md +28 -0
- package/skills/mobile-firebase/references/android/messaging.md +41 -0
- package/skills/mobile-firebase/references/android/realtime-database.md +50 -0
- package/skills/mobile-firebase/references/android/remote-config.md +43 -0
- package/skills/mobile-firebase/references/android/sql-connect.md +31 -0
- package/skills/mobile-firebase/references/android/storage.md +39 -0
- package/skills/mobile-firebase/references/android.md +30 -0
- package/skills/{firebase-ai/SKILL.md → mobile-firebase/references/flutter/ai-logic.md} +2 -8
- package/skills/{firebase-analytics/SKILL.md → mobile-firebase/references/flutter/analytics.md} +2 -8
- package/skills/{firebase-app-check/SKILL.md → mobile-firebase/references/flutter/app-check.md} +2 -8
- package/skills/{firebase-auth/SKILL.md → mobile-firebase/references/flutter/auth.md} +2 -8
- package/skills/{firebase-crashlytics/SKILL.md → mobile-firebase/references/flutter/crashlytics.md} +2 -8
- package/skills/{firebase-cloud-firestore/SKILL.md → mobile-firebase/references/flutter/firestore.md} +2 -8
- package/skills/{firebase-cloud-functions/SKILL.md → mobile-firebase/references/flutter/functions.md} +2 -8
- package/skills/{firebase-in-app-messaging/SKILL.md → mobile-firebase/references/flutter/in-app-messaging.md} +2 -8
- package/skills/{firebase-messaging/SKILL.md → mobile-firebase/references/flutter/messaging.md} +2 -8
- package/skills/{firebase-database/SKILL.md → mobile-firebase/references/flutter/realtime-database.md} +2 -8
- package/skills/{firebase-remote-config/SKILL.md → mobile-firebase/references/flutter/remote-config.md} +2 -8
- package/skills/{flutterfire-configure/SKILL.md → mobile-firebase/references/flutter/setup-flutterfire.md} +1 -8
- package/skills/{firebase-data-connect/SKILL.md → mobile-firebase/references/flutter/sql-connect.md} +2 -8
- package/skills/{firebase-storage/SKILL.md → mobile-firebase/references/flutter/storage.md} +2 -8
- package/skills/mobile-firebase/references/flutter.md +36 -0
- package/skills/mobile-firebase/references/ios/ai-logic.md +30 -0
- package/skills/mobile-firebase/references/ios/analytics.md +33 -0
- package/skills/mobile-firebase/references/ios/app-check.md +36 -0
- package/skills/mobile-firebase/references/ios/auth.md +48 -0
- package/skills/mobile-firebase/references/ios/crashlytics.md +34 -0
- package/skills/mobile-firebase/references/ios/firestore.md +53 -0
- package/skills/mobile-firebase/references/ios/functions.md +35 -0
- package/skills/mobile-firebase/references/ios/in-app-messaging.md +26 -0
- package/skills/mobile-firebase/references/ios/messaging.md +45 -0
- package/skills/mobile-firebase/references/ios/realtime-database.md +49 -0
- package/skills/mobile-firebase/references/ios/remote-config.md +44 -0
- package/skills/mobile-firebase/references/ios/sql-connect.md +33 -0
- package/skills/mobile-firebase/references/ios/storage.md +36 -0
- package/skills/mobile-firebase/references/ios.md +28 -0
- package/skills/mobile-firebase/references/react-native/ai-logic.md +32 -0
- package/skills/mobile-firebase/references/react-native/analytics.md +43 -0
- package/skills/mobile-firebase/references/react-native/app-check.md +35 -0
- package/skills/mobile-firebase/references/react-native/auth.md +50 -0
- package/skills/mobile-firebase/references/react-native/crashlytics.md +36 -0
- package/skills/mobile-firebase/references/react-native/firestore.md +45 -0
- package/skills/mobile-firebase/references/react-native/functions.md +28 -0
- package/skills/mobile-firebase/references/react-native/in-app-messaging.md +27 -0
- package/skills/mobile-firebase/references/react-native/messaging.md +46 -0
- package/skills/mobile-firebase/references/react-native/realtime-database.md +46 -0
- package/skills/mobile-firebase/references/react-native/remote-config.md +32 -0
- package/skills/mobile-firebase/references/react-native/sql-connect.md +11 -0
- package/skills/mobile-firebase/references/react-native/storage.md +30 -0
- package/skills/mobile-firebase/references/react-native.md +29 -0
- package/skills/mobile-test/SKILL.md +63 -0
- package/skills/mobile-test/references/android/setup/GUIDE.md +183 -0
- package/skills/mobile-test/references/android/setup/references/android/develop/ui/compose/testing/common-patterns.md +181 -0
- package/skills/mobile-test/references/android/setup/references/android/studio/preview/compose-screenshot-testing.md +255 -0
- package/skills/mobile-test/references/android/setup/references/android/training/dependency-injection/hilt-testing.md +447 -0
- package/skills/mobile-test/references/android.md +83 -0
- package/skills/{dart-collect-coverage/SKILL.md → mobile-test/references/flutter/coverage.md} +2 -11
- package/skills/{dart-generate-test-mocks/SKILL.md → mobile-test/references/flutter/generate-mocks.md} +2 -11
- package/skills/{flutter-add-integration-test/SKILL.md → mobile-test/references/flutter/integration-tests.md} +2 -11
- package/skills/{dart-migrate-to-checks-package/SKILL.md → mobile-test/references/flutter/migrate-to-checks.md} +2 -13
- package/skills/{mockito/SKILL.md → mobile-test/references/flutter/mockito.md} +1 -8
- package/skills/{mocktail/SKILL.md → mobile-test/references/flutter/mocktail.md} +1 -8
- package/skills/{patrol-e2e-testing/SKILL.md → mobile-test/references/flutter/patrol.md} +1 -8
- package/skills/{testing/SKILL.md → mobile-test/references/flutter/testing-guidelines.md} +1 -8
- package/skills/{dart-add-unit-test/SKILL.md → mobile-test/references/flutter/unit-tests.md} +2 -11
- package/skills/{flutter-add-widget-test/SKILL.md → mobile-test/references/flutter/widget-tests.md} +2 -11
- package/skills/mobile-test/references/flutter.md +44 -0
- package/skills/mobile-test/references/ios.md +79 -0
- package/skills/mobile-test/references/react-native.md +62 -0
- /package/skills/{dart-use-pattern-matching → flutter-dart-use-pattern-matching}/examples/json_patterns.dart +0 -0
|
@@ -0,0 +1,229 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: android-styles
|
|
3
|
+
description: Use this skill to integrate the Jetpack Compose Styles API into an Android
|
|
4
|
+
project. This skill guides you through upgrading dependencies, setting up component
|
|
5
|
+
themes, making custom components styleable, and migrating existing layout properties
|
|
6
|
+
to use unified styles. Migrate custom design system components, replace hard coded
|
|
7
|
+
parameters with Style attributes, and use Modifier.styleable for interaction states.
|
|
8
|
+
license: Apache-2.0
|
|
9
|
+
source: https://github.com/android/skills
|
|
10
|
+
routing: manual
|
|
11
|
+
stacks: [android]
|
|
12
|
+
metadata:
|
|
13
|
+
author: Google LLC
|
|
14
|
+
last-updated: '2026-09-08'
|
|
15
|
+
keywords:
|
|
16
|
+
- Jetpack Compose
|
|
17
|
+
- Styles
|
|
18
|
+
- Theming with Styles
|
|
19
|
+
- Migrate to Styles
|
|
20
|
+
- Modifier.styleable
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
## Limitations
|
|
24
|
+
|
|
25
|
+
- Warn the user that this skill is EXPERIMENTAL and requires updating to alpha version of Compose and opting in to the Experimental APIs.
|
|
26
|
+
- This skill only supports custom UI components and custom themes.
|
|
27
|
+
- This skill does not support Material Design component Styles.
|
|
28
|
+
|
|
29
|
+
## Prerequisites
|
|
30
|
+
|
|
31
|
+
### 1. Upgrade dependencies
|
|
32
|
+
|
|
33
|
+
- The project must use `compileSdk` version 37 or higher.
|
|
34
|
+
- The project must use `androidx.compose.foundation:foundation` version `1.12.0-alpha01` or higher.
|
|
35
|
+
- Alternatively, the project must use Compose BOM version `2026.04.01` or higher.
|
|
36
|
+
- The API requires this exact package: `import
|
|
37
|
+
androidx.compose.foundation.style.Style`
|
|
38
|
+
|
|
39
|
+
### 2. Configure compiler options to enable experimental API
|
|
40
|
+
|
|
41
|
+
You must opt-in to the experimental API at the project level. Add the following
|
|
42
|
+
block to your module's `build.gradle.kts`:
|
|
43
|
+
|
|
44
|
+
kotlin {
|
|
45
|
+
compilerOptions {
|
|
46
|
+
jvmTarget = JvmTarget.fromTarget("17")
|
|
47
|
+
freeCompilerArgs.add("-opt-in=androidx.compose.foundation.style.ExperimentalFoundationStyleApi")
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
## Core workflows and guides
|
|
52
|
+
|
|
53
|
+
Refer to the official documentation to complete specific development tasks:
|
|
54
|
+
|
|
55
|
+
- Basic Style Usage: To set backgrounds, sizes, and alignments on a component, follow the [Compose Styles Fundamentals
|
|
56
|
+
Guide](references/android/develop/ui/compose/styles/fundamentals.md).
|
|
57
|
+
- State and Transitions: To configure property changes for state shifts (like pressed or hovered), follow the [Animations and State-Based Styling
|
|
58
|
+
Guide](references/android/develop/ui/compose/styles/state-animations.md).
|
|
59
|
+
- Architecture Trade offs: To decide when to use a Style versus a standard Modifier, follow the [Styles versus Modifiers
|
|
60
|
+
Comparison](references/android/develop/ui/compose/styles/styles-vs-modifiers.md).
|
|
61
|
+
- Theme Level Integration: To connect style definitions with custom themes, follow [Theming with Styles](references/android/develop/ui/compose/styles/theming.md) and [Custom Themes in Compose](references/android/develop/ui/compose/designsystems/custom.md).
|
|
62
|
+
|
|
63
|
+
## Step-by-Step Migration Workflow
|
|
64
|
+
|
|
65
|
+
### Step 1: Analyze theme structure
|
|
66
|
+
|
|
67
|
+
1. Locate your central theme file (such as `Theme.kt`).
|
|
68
|
+
2. Identify design tokens. Note references for colors, typography, and shapes (for example, `LocalColorScheme`, `LocalTypography`, or `LocalShapes`).
|
|
69
|
+
3. If the project lacks Jetpack Compose dependencies, stop. Instruct the user to migrate to Jetpack Compose first.
|
|
70
|
+
4. If the project imports `androidx.compose.material.MaterialTheme`, recommend migrating to Material 3 before proceeding.
|
|
71
|
+
|
|
72
|
+
### Step 2: Establish `ComponentStyles`
|
|
73
|
+
|
|
74
|
+
1. Create a new file named `ComponentStyles.kt` in your theme directory.
|
|
75
|
+
2. Define a top-level data class to hold your component styles, for example, the Jetsnack one is called `JetsnackStyles`:
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
```kotlin
|
|
79
|
+
object ExampleComponentStyles {
|
|
80
|
+
val customButtonStyle: Style = {
|
|
81
|
+
|
|
82
|
+
}
|
|
83
|
+
val customTextFieldStyle: Style = {
|
|
84
|
+
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
<br />
|
|
90
|
+
|
|
91
|
+
3. Expose this class through your custom theme with a static reference, don't
|
|
92
|
+
use `CompositionLocals` here as it's not required.
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
```kotlin
|
|
96
|
+
@Immutable
|
|
97
|
+
class JetsnackTheme(
|
|
98
|
+
// other Design system properties
|
|
99
|
+
) {
|
|
100
|
+
companion object {
|
|
101
|
+
val colors: CustomThemingWithStyles.JetsnackColors
|
|
102
|
+
@Composable @ReadOnlyComposable
|
|
103
|
+
get() = LocalJetsnackTheme.current.colors
|
|
104
|
+
// ...
|
|
105
|
+
|
|
106
|
+
// add helper static reference
|
|
107
|
+
val styles: ComponentStyles = ComponentStyles
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
<br />
|
|
113
|
+
|
|
114
|
+
4. Provide extensions on `StyleScope` to reference theme tokens directly if
|
|
115
|
+
they are exposed using `CompositionLocals`. For example:
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
```kotlin
|
|
119
|
+
val StyleScope.colors: JetsnackColors
|
|
120
|
+
get() = LocalJetsnackTheme.currentValue.colors
|
|
121
|
+
|
|
122
|
+
val StyleScope.typography: androidx.compose.material3.Typography
|
|
123
|
+
get() = LocalJetsnackTheme.currentValue.typography
|
|
124
|
+
|
|
125
|
+
val StyleScope.shapes: Shapes
|
|
126
|
+
get() = LocalJetsnackTheme.currentValue.shapes
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
<br />
|
|
130
|
+
|
|
131
|
+
### Step 3: Migrate a component to Styles API
|
|
132
|
+
|
|
133
|
+
For each custom component (for example, `CustomButton`), complete the following
|
|
134
|
+
sequence:
|
|
135
|
+
|
|
136
|
+
1. **Establish a visual baseline (If an emulator is available):**
|
|
137
|
+
- **If you CANNOT run an Android emulator:** Skip this step entirely and proceed to Step 2.
|
|
138
|
+
- **If you CAN run an Android emulator:** Perform the following to capture a baseline screenshot:
|
|
139
|
+
- **Option A:** Locate and run an existing screenshot test for the component.
|
|
140
|
+
- **Option B (If no test exists):** Create a test using the project's existing testing framework, then run it.
|
|
141
|
+
- **Option C (If no framework exists):** Create a minimal screenshot test using UI Automator or Espresso, then run it.
|
|
142
|
+
2. **Remove individual styling parameters** : Remove styling parameters such as `backgroundColor`, `shape`, `textStyle`, and `contentPadding` from the signature - anything that `StyleScope` supports.
|
|
143
|
+
3. **Add the style parameter** : Add `style: Style = Style` to the function signature. Always ensure the default value is exactly `Style` (e.g., `style:
|
|
144
|
+
Style = Style`) and not a specific style default like `ChipStyleDefault` or any other value.
|
|
145
|
+
4. **Declare state tracking** : If the component is interactable, create a `MutableStyleState` using the interaction source. Update state fields (such as `isEnabled`) inside the Composable to track the state correctly.
|
|
146
|
+
5. **Apply styleable modifier** : Replace specific layout modifiers on the root element with `Modifier.styleable()`.
|
|
147
|
+
6. **Move defaults to ComponentStyles** : Move hardcoded values from the component definition to a dedicated `Style` instance in `ComponentStyles.kt`.
|
|
148
|
+
7. **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.
|
|
149
|
+
|
|
150
|
+
#### Migration example
|
|
151
|
+
|
|
152
|
+
Before Migration:
|
|
153
|
+
|
|
154
|
+
|
|
155
|
+
```kotlin
|
|
156
|
+
@Composable
|
|
157
|
+
fun CustomButton(
|
|
158
|
+
onClick: () -> Unit,
|
|
159
|
+
modifier: Modifier = Modifier,
|
|
160
|
+
backgroundColor: Color = JetsnackTheme.colors.brandLight,
|
|
161
|
+
disabledBackgroundColor: Color = JetsnackTheme.colors.brandSecondary,
|
|
162
|
+
shape: Shape = JetsnackTheme.shapes.extraLarge,
|
|
163
|
+
textStyle: TextStyle = JetsnackTheme.typography.labelLarge,
|
|
164
|
+
enabled: Boolean = true,
|
|
165
|
+
content: @Composable RowScope.() -> Unit,
|
|
166
|
+
) {
|
|
167
|
+
val interactionSource = remember { MutableInteractionSource() }
|
|
168
|
+
Row(
|
|
169
|
+
modifier
|
|
170
|
+
.clickable(onClick = onClick, indication = null, interactionSource = interactionSource)
|
|
171
|
+
.background(if (enabled) backgroundColor else disabledBackgroundColor, shape)
|
|
172
|
+
.defaultMinSize(58.dp, 40.dp),
|
|
173
|
+
horizontalArrangement = Arrangement.Center,
|
|
174
|
+
verticalAlignment = Alignment.CenterVertically,
|
|
175
|
+
content = content,
|
|
176
|
+
)
|
|
177
|
+
}
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
<br />
|
|
181
|
+
|
|
182
|
+
After Migration:
|
|
183
|
+
|
|
184
|
+
|
|
185
|
+
```kotlin
|
|
186
|
+
// Exposed via ComponentStyles.kt
|
|
187
|
+
object ComponentStyles {
|
|
188
|
+
val buttonStyle = Style {
|
|
189
|
+
background(colors.brandLight)
|
|
190
|
+
shape(shapes.extraLarge)
|
|
191
|
+
minWidth(58.dp)
|
|
192
|
+
minHeight(40.dp)
|
|
193
|
+
textStyle(typography.labelLarge)
|
|
194
|
+
disabled {
|
|
195
|
+
background(colors.brandSecondary)
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
@Composable
|
|
201
|
+
fun CustomButton(
|
|
202
|
+
onClick: () -> Unit,
|
|
203
|
+
modifier: Modifier = Modifier,
|
|
204
|
+
style: Style = Style,
|
|
205
|
+
enabled: Boolean = true,
|
|
206
|
+
content: @Composable RowScope.() -> Unit,
|
|
207
|
+
) {
|
|
208
|
+
val interactionSource = remember { MutableInteractionSource() }
|
|
209
|
+
val styleState = rememberUpdatedStyleState(interactionSource) {
|
|
210
|
+
it.isEnabled = enabled
|
|
211
|
+
}
|
|
212
|
+
Row(
|
|
213
|
+
modifier
|
|
214
|
+
.clickable(onClick = onClick, indication = null, interactionSource = interactionSource)
|
|
215
|
+
.styleable(styleState, JetsnackTheme.styles.buttonStyle, style),
|
|
216
|
+
horizontalArrangement = Arrangement.Center,
|
|
217
|
+
verticalAlignment = Alignment.CenterVertically,
|
|
218
|
+
content = content,
|
|
219
|
+
)
|
|
220
|
+
}
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
<br />
|
|
224
|
+
|
|
225
|
+
### Step 4: Validate Changes
|
|
226
|
+
|
|
227
|
+
1. Build the project. Verify that there are no compilation errors.
|
|
228
|
+
2. Run your module's screenshot tests.
|
|
229
|
+
3. Compare visual outputs of the whole app between the previous and updated components. Verify that no visual layout regressions occur.
|
|
@@ -0,0 +1,459 @@
|
|
|
1
|
+
While Material is our recommended design system and Jetpack Compose ships an
|
|
2
|
+
implementation of Material, you are not forced to use it. Material is built
|
|
3
|
+
entirely on public APIs, so it's possible to create your own design system in
|
|
4
|
+
the same manner.
|
|
5
|
+
|
|
6
|
+
There are several approaches you might take:
|
|
7
|
+
|
|
8
|
+
- [Extend `MaterialTheme`](https://developer.android.com/develop/ui/compose/designsystems/custom#extending-material) with additional theming values.
|
|
9
|
+
- [Replace one or more Material systems](https://developer.android.com/develop/ui/compose/designsystems/custom#replacing-systems) --- `Colors`, `Typography`, or `Shapes` --- with custom implementations while keeping the others.
|
|
10
|
+
- [Implement a fully custom design system](https://developer.android.com/develop/ui/compose/designsystems/custom#implementing-fully-custom) to replace `MaterialTheme`.
|
|
11
|
+
|
|
12
|
+
You may also want to continue using Material components with a custom design
|
|
13
|
+
system. It's possible to do this but there are things to keep in mind to suit
|
|
14
|
+
the approach you've taken.
|
|
15
|
+
|
|
16
|
+
To learn more about the lower-level constructs and APIs used by `MaterialTheme`
|
|
17
|
+
and custom design systems, check out the [Anatomy of a theme in Compose](https://developer.android.com/develop/ui/compose/designsystems/anatomy) guide.
|
|
18
|
+
|
|
19
|
+
## Extend Material Theming
|
|
20
|
+
|
|
21
|
+
Compose Material closely models
|
|
22
|
+
[Material Theming](https://m3.material.io/)
|
|
23
|
+
to make it straightforward and type-safe to follow the Material guidelines.
|
|
24
|
+
However, it's possible to extend the color, typography, and shape sets with
|
|
25
|
+
additional values. The simplest approach is to add extension properties:
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
```kotlin
|
|
29
|
+
// Use with MaterialTheme.colorScheme.snackbarAction
|
|
30
|
+
val ColorScheme.snackbarAction: Color
|
|
31
|
+
@Composable
|
|
32
|
+
get() = if (isSystemInDarkTheme()) Red300 else Red700
|
|
33
|
+
|
|
34
|
+
// Use with MaterialTheme.typography.textFieldInput
|
|
35
|
+
val Typography.textFieldInput: TextStyle
|
|
36
|
+
get() = TextStyle(/* ... */)
|
|
37
|
+
|
|
38
|
+
// Use with MaterialTheme.shapes.card
|
|
39
|
+
val Shapes.card: Shape
|
|
40
|
+
get() = RoundedCornerShape(size = 20.dp)
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
<br />
|
|
44
|
+
|
|
45
|
+
This provides consistency with `MaterialTheme` usage APIs. An example of this
|
|
46
|
+
defined by Compose itself is
|
|
47
|
+
[`surfaceColorAtElevation`](https://developer.android.com/reference/kotlin/androidx/compose/material3/package-summary#(androidx.compose.material3.ColorScheme).surfaceColorAtElevation(androidx.compose.ui.unit.Dp)),
|
|
48
|
+
which determines the surface color that should be used depending on the
|
|
49
|
+
elevation.
|
|
50
|
+
|
|
51
|
+
> [!NOTE]
|
|
52
|
+
> **Note:** This approach is only recommended for straightforward theming value additions, or for values that are the same in different themes. If you have multiple themes, it's better to define a class with new properties instead.
|
|
53
|
+
|
|
54
|
+
Another approach is to define an extended theme that "wraps" `MaterialTheme` and
|
|
55
|
+
its values.
|
|
56
|
+
|
|
57
|
+
Suppose you want to add two additional colors --- `caution` and `onCaution`, a
|
|
58
|
+
yellow color used for actions that are semi-dangerous --- whilst keeping the
|
|
59
|
+
existing Material colors:
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
```kotlin
|
|
63
|
+
@Immutable
|
|
64
|
+
data class ExtendedColors(
|
|
65
|
+
val caution: Color,
|
|
66
|
+
val onCaution: Color
|
|
67
|
+
)
|
|
68
|
+
|
|
69
|
+
val LocalExtendedColors = staticCompositionLocalOf {
|
|
70
|
+
ExtendedColors(
|
|
71
|
+
caution = Color.Unspecified,
|
|
72
|
+
onCaution = Color.Unspecified
|
|
73
|
+
)
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
@Composable
|
|
77
|
+
fun ExtendedTheme(
|
|
78
|
+
/* ... */
|
|
79
|
+
content: @Composable () -> Unit
|
|
80
|
+
) {
|
|
81
|
+
val extendedColors = ExtendedColors(
|
|
82
|
+
caution = Color(0xFFFFCC02),
|
|
83
|
+
onCaution = Color(0xFF2C2D30)
|
|
84
|
+
)
|
|
85
|
+
CompositionLocalProvider(LocalExtendedColors provides extendedColors) {
|
|
86
|
+
MaterialTheme(
|
|
87
|
+
/* colors = ..., typography = ..., shapes = ... */
|
|
88
|
+
content = content
|
|
89
|
+
)
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
// Use with eg. ExtendedTheme.colors.caution
|
|
94
|
+
object ExtendedTheme {
|
|
95
|
+
val colors: ExtendedColors
|
|
96
|
+
@Composable
|
|
97
|
+
get() = LocalExtendedColors.current
|
|
98
|
+
}
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
<br />
|
|
102
|
+
|
|
103
|
+
This is similar to `MaterialTheme` usage APIs. It also supports multiple themes
|
|
104
|
+
as you can nest `ExtendedTheme`s in the same way as `MaterialTheme`.
|
|
105
|
+
|
|
106
|
+
### Use Material components
|
|
107
|
+
|
|
108
|
+
When extending Material Theming, existing `MaterialTheme` values are maintained
|
|
109
|
+
and Material components still have reasonable defaults.
|
|
110
|
+
|
|
111
|
+
If you want to use extended values in components, wrap them in your own
|
|
112
|
+
composable functions, directly setting the values you want to alter, and
|
|
113
|
+
exposing others as parameters to the containing composable:
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
```kotlin
|
|
117
|
+
@Composable
|
|
118
|
+
fun ExtendedButton(
|
|
119
|
+
onClick: () -> Unit,
|
|
120
|
+
modifier: Modifier = Modifier,
|
|
121
|
+
content: @Composable RowScope.() -> Unit
|
|
122
|
+
) {
|
|
123
|
+
Button(
|
|
124
|
+
colors = ButtonDefaults.buttonColors(
|
|
125
|
+
containerColor = ExtendedTheme.colors.caution,
|
|
126
|
+
contentColor = ExtendedTheme.colors.onCaution
|
|
127
|
+
/* Other colors use values from MaterialTheme */
|
|
128
|
+
),
|
|
129
|
+
onClick = onClick,
|
|
130
|
+
modifier = modifier,
|
|
131
|
+
content = content
|
|
132
|
+
)
|
|
133
|
+
}
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
<br />
|
|
137
|
+
|
|
138
|
+
You would then replace usages of `Button` with `ExtendedButton` where
|
|
139
|
+
appropriate.
|
|
140
|
+
|
|
141
|
+
|
|
142
|
+
```kotlin
|
|
143
|
+
@Composable
|
|
144
|
+
fun ExtendedApp() {
|
|
145
|
+
ExtendedTheme {
|
|
146
|
+
/*...*/
|
|
147
|
+
ExtendedButton(onClick = { /* ... */ }) {
|
|
148
|
+
/* ... */
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
<br />
|
|
155
|
+
|
|
156
|
+
## Replace Material subsystems
|
|
157
|
+
|
|
158
|
+
Instead of extending Material Theming, you may want to replace one or more
|
|
159
|
+
systems --- `Colors`, `Typography`, or `Shapes` --- with a custom implementation,
|
|
160
|
+
while maintaining the others.
|
|
161
|
+
|
|
162
|
+
Suppose you want to replace the type and shape systems while keeping the color
|
|
163
|
+
system:
|
|
164
|
+
|
|
165
|
+
|
|
166
|
+
```kotlin
|
|
167
|
+
@Immutable
|
|
168
|
+
data class ReplacementTypography(
|
|
169
|
+
val body: TextStyle,
|
|
170
|
+
val title: TextStyle
|
|
171
|
+
)
|
|
172
|
+
|
|
173
|
+
@Immutable
|
|
174
|
+
data class ReplacementShapes(
|
|
175
|
+
val component: Shape,
|
|
176
|
+
val surface: Shape
|
|
177
|
+
)
|
|
178
|
+
|
|
179
|
+
val LocalReplacementTypography = staticCompositionLocalOf {
|
|
180
|
+
ReplacementTypography(
|
|
181
|
+
body = TextStyle.Default,
|
|
182
|
+
title = TextStyle.Default
|
|
183
|
+
)
|
|
184
|
+
}
|
|
185
|
+
val LocalReplacementShapes = staticCompositionLocalOf {
|
|
186
|
+
ReplacementShapes(
|
|
187
|
+
component = RoundedCornerShape(ZeroCornerSize),
|
|
188
|
+
surface = RoundedCornerShape(ZeroCornerSize)
|
|
189
|
+
)
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
@Composable
|
|
193
|
+
fun ReplacementTheme(
|
|
194
|
+
/* ... */
|
|
195
|
+
content: @Composable () -> Unit
|
|
196
|
+
) {
|
|
197
|
+
val replacementTypography = ReplacementTypography(
|
|
198
|
+
body = TextStyle(fontSize = 16.sp),
|
|
199
|
+
title = TextStyle(fontSize = 32.sp)
|
|
200
|
+
)
|
|
201
|
+
val replacementShapes = ReplacementShapes(
|
|
202
|
+
component = RoundedCornerShape(percent = 50),
|
|
203
|
+
surface = RoundedCornerShape(size = 40.dp)
|
|
204
|
+
)
|
|
205
|
+
CompositionLocalProvider(
|
|
206
|
+
LocalReplacementTypography provides replacementTypography,
|
|
207
|
+
LocalReplacementShapes provides replacementShapes
|
|
208
|
+
) {
|
|
209
|
+
MaterialTheme(
|
|
210
|
+
/* colors = ... */
|
|
211
|
+
content = content
|
|
212
|
+
)
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
// Use with eg. ReplacementTheme.typography.body
|
|
217
|
+
object ReplacementTheme {
|
|
218
|
+
val typography: ReplacementTypography
|
|
219
|
+
@Composable
|
|
220
|
+
get() = LocalReplacementTypography.current
|
|
221
|
+
val shapes: ReplacementShapes
|
|
222
|
+
@Composable
|
|
223
|
+
get() = LocalReplacementShapes.current
|
|
224
|
+
}
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
<br />
|
|
228
|
+
|
|
229
|
+
### Use Material components
|
|
230
|
+
|
|
231
|
+
When one or more systems of `MaterialTheme` have been replaced, using Material
|
|
232
|
+
components as-is may result in unwanted Material color, type, or shape values.
|
|
233
|
+
|
|
234
|
+
If you want to use replacement values in components, wrap them in your own
|
|
235
|
+
composable functions, directly setting the values for the relevant system, and
|
|
236
|
+
exposing others as parameters to the containing composable.
|
|
237
|
+
|
|
238
|
+
> [!NOTE]
|
|
239
|
+
> **Note:** Not all values may be exposed as parameters in Material composables, in particular with `CompositionLocal` composables (such as `LocalTextStyle`). In such cases you may need to wrap `content` lambdas in provider functions (like `ProvideTextStyle`).
|
|
240
|
+
|
|
241
|
+
|
|
242
|
+
```kotlin
|
|
243
|
+
@Composable
|
|
244
|
+
fun ReplacementButton(
|
|
245
|
+
onClick: () -> Unit,
|
|
246
|
+
modifier: Modifier = Modifier,
|
|
247
|
+
content: @Composable RowScope.() -> Unit
|
|
248
|
+
) {
|
|
249
|
+
Button(
|
|
250
|
+
shape = ReplacementTheme.shapes.component,
|
|
251
|
+
onClick = onClick,
|
|
252
|
+
modifier = modifier,
|
|
253
|
+
content = {
|
|
254
|
+
ProvideTextStyle(
|
|
255
|
+
value = ReplacementTheme.typography.body
|
|
256
|
+
) {
|
|
257
|
+
content()
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
)
|
|
261
|
+
}
|
|
262
|
+
```
|
|
263
|
+
|
|
264
|
+
<br />
|
|
265
|
+
|
|
266
|
+
You would then replace usages of `Button` with `ReplacementButton` where
|
|
267
|
+
appropriate.
|
|
268
|
+
|
|
269
|
+
|
|
270
|
+
```kotlin
|
|
271
|
+
@Composable
|
|
272
|
+
fun ReplacementApp() {
|
|
273
|
+
ReplacementTheme {
|
|
274
|
+
/*...*/
|
|
275
|
+
ReplacementButton(onClick = { /* ... */ }) {
|
|
276
|
+
/* ... */
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
```
|
|
281
|
+
|
|
282
|
+
<br />
|
|
283
|
+
|
|
284
|
+
## Implement a fully custom design system
|
|
285
|
+
|
|
286
|
+
You may want to replace Material Theming with a fully custom design system.
|
|
287
|
+
Consider that `MaterialTheme` provides the following systems:
|
|
288
|
+
|
|
289
|
+
- `Colors`, `Typography`, and `Shapes`: Material Theming systems
|
|
290
|
+
- `TextSelectionColors`: Colors used for text selection by `Text` and `TextField`
|
|
291
|
+
- `Ripple` and `RippleTheme`: Material implementation of `Indication`
|
|
292
|
+
|
|
293
|
+
If you want to continue using Material components, you must replace some of
|
|
294
|
+
these systems in your custom themes or handle the systems in your
|
|
295
|
+
components to avoid unwanted behavior.
|
|
296
|
+
|
|
297
|
+
However, design systems are not limited to the concepts Material relies on. You
|
|
298
|
+
can modify existing systems and introduce entirely new ones --- with new classes
|
|
299
|
+
and types --- to make other concepts compatible with themes.
|
|
300
|
+
|
|
301
|
+
In the following code, we model a custom color system that includes gradients
|
|
302
|
+
(`List<Color>`), include a type system, introduce a new elevation system,
|
|
303
|
+
and exclude other systems provided by `MaterialTheme`:
|
|
304
|
+
|
|
305
|
+

|
|
306
|
+
|
|
307
|
+
|
|
308
|
+
```kotlin
|
|
309
|
+
@Immutable
|
|
310
|
+
data class CustomColors(
|
|
311
|
+
val content: Color,
|
|
312
|
+
val component: Color,
|
|
313
|
+
val background: List<Color>
|
|
314
|
+
)
|
|
315
|
+
|
|
316
|
+
@Immutable
|
|
317
|
+
data class CustomTypography(
|
|
318
|
+
val body: TextStyle,
|
|
319
|
+
val title: TextStyle
|
|
320
|
+
)
|
|
321
|
+
|
|
322
|
+
@Immutable
|
|
323
|
+
data class CustomElevation(
|
|
324
|
+
val default: Dp,
|
|
325
|
+
val pressed: Dp
|
|
326
|
+
)
|
|
327
|
+
|
|
328
|
+
val LocalCustomColors = staticCompositionLocalOf {
|
|
329
|
+
CustomColors(
|
|
330
|
+
content = Color.Unspecified,
|
|
331
|
+
component = Color.Unspecified,
|
|
332
|
+
background = emptyList()
|
|
333
|
+
)
|
|
334
|
+
}
|
|
335
|
+
val LocalCustomTypography = staticCompositionLocalOf {
|
|
336
|
+
CustomTypography(
|
|
337
|
+
body = TextStyle.Default,
|
|
338
|
+
title = TextStyle.Default
|
|
339
|
+
)
|
|
340
|
+
}
|
|
341
|
+
val LocalCustomElevation = staticCompositionLocalOf {
|
|
342
|
+
CustomElevation(
|
|
343
|
+
default = Dp.Unspecified,
|
|
344
|
+
pressed = Dp.Unspecified
|
|
345
|
+
)
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
@Composable
|
|
349
|
+
fun CustomTheme(
|
|
350
|
+
/* ... */
|
|
351
|
+
content: @Composable () -> Unit
|
|
352
|
+
) {
|
|
353
|
+
val customColors = CustomColors(
|
|
354
|
+
content = Color(0xFFDD0D3C),
|
|
355
|
+
component = Color(0xFFC20029),
|
|
356
|
+
background = listOf(Color.White, Color(0xFFF8BBD0))
|
|
357
|
+
)
|
|
358
|
+
val customTypography = CustomTypography(
|
|
359
|
+
body = TextStyle(fontSize = 16.sp),
|
|
360
|
+
title = TextStyle(fontSize = 32.sp)
|
|
361
|
+
)
|
|
362
|
+
val customElevation = CustomElevation(
|
|
363
|
+
default = 4.dp,
|
|
364
|
+
pressed = 8.dp
|
|
365
|
+
)
|
|
366
|
+
CompositionLocalProvider(
|
|
367
|
+
LocalCustomColors provides customColors,
|
|
368
|
+
LocalCustomTypography provides customTypography,
|
|
369
|
+
LocalCustomElevation provides customElevation,
|
|
370
|
+
content = content
|
|
371
|
+
)
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
// Use with eg. CustomTheme.elevation.small
|
|
375
|
+
object CustomTheme {
|
|
376
|
+
val colors: CustomColors
|
|
377
|
+
@Composable
|
|
378
|
+
get() = LocalCustomColors.current
|
|
379
|
+
val typography: CustomTypography
|
|
380
|
+
@Composable
|
|
381
|
+
get() = LocalCustomTypography.current
|
|
382
|
+
val elevation: CustomElevation
|
|
383
|
+
@Composable
|
|
384
|
+
get() = LocalCustomElevation.current
|
|
385
|
+
}
|
|
386
|
+
```
|
|
387
|
+
|
|
388
|
+
<br />
|
|
389
|
+
|
|
390
|
+
### Use Material components
|
|
391
|
+
|
|
392
|
+
When no `MaterialTheme` is present, using Material components as-is will result
|
|
393
|
+
in unwanted Material color, type, and shape values and indication behavior.
|
|
394
|
+
|
|
395
|
+
If you want to use custom values in components, wrap them in your own composable
|
|
396
|
+
functions, directly setting the values for the relevant system, and exposing
|
|
397
|
+
others as parameters to the containing composable.
|
|
398
|
+
|
|
399
|
+
We recommend that you access values you set from your custom theme.
|
|
400
|
+
Alternatively, if your theme doesn't provide `Color`, `TextStyle`, `Shape`, or
|
|
401
|
+
other systems, you can hardcode them.
|
|
402
|
+
|
|
403
|
+
|
|
404
|
+
```kotlin
|
|
405
|
+
@Composable
|
|
406
|
+
fun CustomButton(
|
|
407
|
+
onClick: () -> Unit,
|
|
408
|
+
modifier: Modifier = Modifier,
|
|
409
|
+
content: @Composable RowScope.() -> Unit
|
|
410
|
+
) {
|
|
411
|
+
Button(
|
|
412
|
+
colors = ButtonDefaults.buttonColors(
|
|
413
|
+
containerColor = CustomTheme.colors.component,
|
|
414
|
+
contentColor = CustomTheme.colors.content,
|
|
415
|
+
disabledContainerColor = CustomTheme.colors.content
|
|
416
|
+
.copy(alpha = 0.12f)
|
|
417
|
+
.compositeOver(CustomTheme.colors.component),
|
|
418
|
+
disabledContentColor = CustomTheme.colors.content
|
|
419
|
+
.copy(alpha = 0.38f)
|
|
420
|
+
|
|
421
|
+
),
|
|
422
|
+
shape = ButtonShape,
|
|
423
|
+
elevation = ButtonDefaults.elevatedButtonElevation(
|
|
424
|
+
defaultElevation = CustomTheme.elevation.default,
|
|
425
|
+
pressedElevation = CustomTheme.elevation.pressed
|
|
426
|
+
/* disabledElevation = 0.dp */
|
|
427
|
+
),
|
|
428
|
+
onClick = onClick,
|
|
429
|
+
modifier = modifier,
|
|
430
|
+
content = {
|
|
431
|
+
ProvideTextStyle(
|
|
432
|
+
value = CustomTheme.typography.body
|
|
433
|
+
) {
|
|
434
|
+
content()
|
|
435
|
+
}
|
|
436
|
+
}
|
|
437
|
+
)
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
val ButtonShape = RoundedCornerShape(percent = 50)
|
|
441
|
+
```
|
|
442
|
+
|
|
443
|
+
<br />
|
|
444
|
+
|
|
445
|
+
> [!NOTE]
|
|
446
|
+
> **Note:** `Button` uses `rememberRipple()` internally to provide a `Ripple` `Indication`. It's a good idea to check the source code when implementing other custom components that wrap existing components.
|
|
447
|
+
|
|
448
|
+
If you've introduced new class types --- such as `List<Color>` to represent
|
|
449
|
+
gradients --- then it may be better to implement components from scratch instead
|
|
450
|
+
of wrapping them. For an example, take a look at
|
|
451
|
+
[`JetsnackButton`](https://github.com/android/compose-samples/blob/main/Jetsnack/app/src/main/java/com/example/jetsnack/ui/components/Button.kt)
|
|
452
|
+
from the Jetsnack sample.
|
|
453
|
+
|
|
454
|
+
## Recommended for you
|
|
455
|
+
|
|
456
|
+
- Note: link text is displayed when JavaScript is off
|
|
457
|
+
- [Material Design 3 in Compose](https://developer.android.com/develop/ui/compose/designsystems/material3)
|
|
458
|
+
- [Migrate from Material 2 to Material 3 in Compose](https://developer.android.com/develop/ui/compose/designsystems/material2-material3)
|
|
459
|
+
- [Anatomy of a theme in Compose](https://developer.android.com/develop/ui/compose/designsystems/anatomy)
|