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.
Files changed (463) hide show
  1. package/.claude-plugin/marketplace.json +2 -2
  2. package/.claude-plugin/plugin.json +1 -1
  3. package/CHANGELOG.md +24 -0
  4. package/README.md +175 -168
  5. package/THIRD_PARTY_NOTICES.md +224 -4
  6. package/agents/android-architect.md +89 -0
  7. package/agents/android-performance-engineer.md +92 -0
  8. package/agents/android-test-engineer.md +97 -0
  9. package/agents/flutter-test-engineer.md +2 -0
  10. package/agents/ios-architect.md +93 -0
  11. package/agents/ios-performance-engineer.md +92 -0
  12. package/agents/ios-test-engineer.md +95 -0
  13. package/agents/lead-mobile.md +10 -1
  14. package/agents/mobile-staff-engineer.md +1 -1
  15. package/agents/rn-architect.md +94 -0
  16. package/agents/rn-performance-engineer.md +92 -0
  17. package/agents/rn-test-engineer.md +98 -0
  18. package/bin/reis-mobile.mjs +59 -17
  19. package/commands/debate.md +10 -1
  20. package/commands/debug.md +60 -0
  21. package/commands/reis-mobile.md +7 -2
  22. package/core/config/project.mjs +59 -0
  23. package/core/registry/frontmatter.mjs +15 -4
  24. package/core/registry/registry.mjs +21 -1
  25. package/core/router/intents.mjs +2 -0
  26. package/core/router/router.mjs +10 -5
  27. package/package.json +1 -1
  28. package/skills/android-adaptive/SKILL.md +304 -0
  29. package/skills/android-adaptive/references/android/develop/ui/compose/layouts/adaptive/flexbox/container-behavior.md +112 -0
  30. package/skills/android-adaptive/references/android/develop/ui/compose/layouts/adaptive/flexbox/get-started.md +69 -0
  31. package/skills/android-adaptive/references/android/develop/ui/compose/layouts/adaptive/flexbox/index.md +81 -0
  32. package/skills/android-adaptive/references/android/develop/ui/compose/layouts/adaptive/flexbox/item-behavior.md +170 -0
  33. package/skills/android-adaptive/references/android/develop/ui/compose/layouts/adaptive/grid/container-properties.md +415 -0
  34. package/skills/android-adaptive/references/android/develop/ui/compose/layouts/adaptive/grid/get-started.md +51 -0
  35. package/skills/android-adaptive/references/android/develop/ui/compose/layouts/adaptive/grid/index.md +73 -0
  36. package/skills/android-adaptive/references/android/develop/ui/compose/layouts/adaptive/grid/item-properties.md +170 -0
  37. package/skills/android-adaptive/references/android/develop/ui/compose/layouts/adaptive/mediaquery/index.md +333 -0
  38. package/skills/android-adaptive/references/android/develop/ui/compose/tooling/debug.md +114 -0
  39. package/skills/android-adaptive/references/android/guide/navigation/navigation-3/recipes/material-listdetail.md +141 -0
  40. package/skills/android-agp-9-upgrade/SKILL.md +106 -0
  41. package/skills/android-agp-9-upgrade/references/android/build/migrate-to-built-in-kotlin.md +416 -0
  42. package/skills/android-agp-9-upgrade/references/android/build/releases/agp-9-0-0-release-notes.md +554 -0
  43. package/skills/android-agp-9-upgrade/references/buildconfig.md +54 -0
  44. package/skills/android-agp-9-upgrade/references/ksp-kapt.md +39 -0
  45. package/skills/android-agp-9-upgrade/references/paparazzi-gradle-9.md +30 -0
  46. package/skills/android-agp-9-upgrade/references/recipes.md +62 -0
  47. package/skills/android-appfunctions/SKILL.md +74 -0
  48. package/skills/android-appfunctions/references/adb-interaction-testing.md +95 -0
  49. package/skills/android-appfunctions/references/context.md +26 -0
  50. package/skills/android-appfunctions/references/feature-discovery-analysis.md +71 -0
  51. package/skills/android-appfunctions/references/implementation-configuration.md +282 -0
  52. package/skills/android-appfunctions/references/kdoc-refinement-optimization.md +75 -0
  53. package/skills/android-appfunctions/references/migrate-to-service-entry-point.md +226 -0
  54. package/skills/android-camerax/SKILL.md +135 -0
  55. package/skills/android-camerax/references/camera1-to-camerax.md +198 -0
  56. package/skills/android-camerax/references/camera2-to-camerax.md +193 -0
  57. package/skills/android-camerax/references/expert-blueprints.md +58 -0
  58. package/skills/android-camerax/references/foldables.md +83 -0
  59. package/skills/android-camerax/references/immutability.md +60 -0
  60. package/skills/android-camerax/references/low-light.md +124 -0
  61. package/skills/android-camerax/references/mlkit-spatial.md +75 -0
  62. package/skills/android-camerax/references/modern-apis.md +42 -0
  63. package/skills/android-camerax/references/testing.md +69 -0
  64. package/skills/android-camerax/references/thermals.md +85 -0
  65. package/skills/android-camerax/references/wear-os.md +76 -0
  66. package/skills/android-camerax/references/xr.md +54 -0
  67. package/skills/android-cli/SKILL.md +474 -0
  68. package/skills/android-cli/references/interact.md +113 -0
  69. package/skills/android-cli/references/journeys.md +120 -0
  70. package/skills/android-code-review/SKILL.md +58 -0
  71. package/skills/android-display-glasses-with-jetpack-compose-glimmer/SKILL.md +340 -0
  72. package/skills/android-display-glasses-with-jetpack-compose-glimmer/references/android/design/ui/ai-glasses/guides/interaction/inputs.md +67 -0
  73. package/skills/android-display-glasses-with-jetpack-compose-glimmer/references/android/develop/xr/jetpack-xr-sdk/access-hardware-projected-context.md +388 -0
  74. package/skills/android-display-glasses-with-jetpack-compose-glimmer/references/android/develop/xr/jetpack-xr-sdk/jetpack-compose-glimmer/buttons.md +139 -0
  75. package/skills/android-display-glasses-with-jetpack-compose-glimmer/references/android/develop/xr/jetpack-xr-sdk/jetpack-compose-glimmer/cards.md +148 -0
  76. package/skills/android-display-glasses-with-jetpack-compose-glimmer/references/android/develop/xr/jetpack-xr-sdk/jetpack-compose-glimmer/focus.md +107 -0
  77. package/skills/android-display-glasses-with-jetpack-compose-glimmer/references/android/develop/xr/jetpack-xr-sdk/jetpack-compose-glimmer/icons.md +90 -0
  78. package/skills/android-display-glasses-with-jetpack-compose-glimmer/references/android/develop/xr/jetpack-xr-sdk/jetpack-compose-glimmer/text.md +69 -0
  79. package/skills/android-display-glasses-with-jetpack-compose-glimmer/references/android/develop/xr/jetpack-xr-sdk/jetpack-compose-glimmer/title-chips.md +82 -0
  80. package/skills/android-display-glasses-with-jetpack-compose-glimmer/references/android/develop/xr/jetpack-xr-sdk/request-hardware-permissions.md +213 -0
  81. package/skills/android-display-glasses-with-jetpack-compose-glimmer/references/button-samples-source.md +176 -0
  82. package/skills/android-display-glasses-with-jetpack-compose-glimmer/references/button-source.md +203 -0
  83. package/skills/android-display-glasses-with-jetpack-compose-glimmer/references/card-samples-source.md +296 -0
  84. package/skills/android-display-glasses-with-jetpack-compose-glimmer/references/card-source.md +515 -0
  85. package/skills/android-display-glasses-with-jetpack-compose-glimmer/references/deptheffect-source.md +224 -0
  86. package/skills/android-display-glasses-with-jetpack-compose-glimmer/references/deptheffectlevels-source.md +105 -0
  87. package/skills/android-display-glasses-with-jetpack-compose-glimmer/references/glimmersansflextypography-source.md +270 -0
  88. package/skills/android-display-glasses-with-jetpack-compose-glimmer/references/glimmertheme-source.md +182 -0
  89. package/skills/android-display-glasses-with-jetpack-compose-glimmer/references/icon-source.md +388 -0
  90. package/skills/android-display-glasses-with-jetpack-compose-glimmer/references/iconbutton-source.md +126 -0
  91. package/skills/android-display-glasses-with-jetpack-compose-glimmer/references/iconsizes-source.md +78 -0
  92. package/skills/android-display-glasses-with-jetpack-compose-glimmer/references/list-source.md +27 -0
  93. package/skills/android-display-glasses-with-jetpack-compose-glimmer/references/listitem-source.md +272 -0
  94. package/skills/android-display-glasses-with-jetpack-compose-glimmer/references/liststate-source.md +427 -0
  95. package/skills/android-display-glasses-with-jetpack-compose-glimmer/references/material-hct-source.md +217 -0
  96. package/skills/android-display-glasses-with-jetpack-compose-glimmer/references/projectedcontext-source.md +265 -0
  97. package/skills/android-display-glasses-with-jetpack-compose-glimmer/references/stack-source.md +368 -0
  98. package/skills/android-display-glasses-with-jetpack-compose-glimmer/references/stackitemscope-source.md +440 -0
  99. package/skills/android-display-glasses-with-jetpack-compose-glimmer/references/stackstate-source.md +325 -0
  100. package/skills/android-display-glasses-with-jetpack-compose-glimmer/references/surface-source.md +1211 -0
  101. package/skills/android-display-glasses-with-jetpack-compose-glimmer/references/titlechip-samples-source.md +101 -0
  102. package/skills/android-display-glasses-with-jetpack-compose-glimmer/references/titlechip-source.md +131 -0
  103. package/skills/android-edge-to-edge/SKILL.md +429 -0
  104. package/skills/android-engage-sdk-integration/SKILL.md +130 -0
  105. package/skills/android-engage-sdk-integration/references/android/guide/playcore/engage/faq.md +439 -0
  106. package/skills/android-engage-sdk-integration/references/android/guide/playcore/engage/food.md +1149 -0
  107. package/skills/android-engage-sdk-integration/references/android/guide/playcore/engage/healthandfitness.md +1055 -0
  108. package/skills/android-engage-sdk-integration/references/android/guide/playcore/engage/listen.md +1050 -0
  109. package/skills/android-engage-sdk-integration/references/android/guide/playcore/engage/otherverticals.md +1301 -0
  110. package/skills/android-engage-sdk-integration/references/android/guide/playcore/engage/read.md +910 -0
  111. package/skills/android-engage-sdk-integration/references/android/guide/playcore/engage/shopping.md +1224 -0
  112. package/skills/android-engage-sdk-integration/references/android/guide/playcore/engage/social.md +719 -0
  113. package/skills/android-engage-sdk-integration/references/android/guide/playcore/engage/travel.md +1413 -0
  114. package/skills/android-engage-sdk-integration/references/android/guide/playcore/engage/tv/continue-watching/index.md +19 -0
  115. package/skills/android-engage-sdk-integration/references/android/guide/playcore/engage/tv/entitlements.md +353 -0
  116. package/skills/android-engage-sdk-integration/references/android/guide/playcore/engage/tv/getting-started.md +202 -0
  117. package/skills/android-engage-sdk-integration/references/android/guide/playcore/engage/tv/recommendations.md +471 -0
  118. package/skills/android-engage-sdk-integration/references/android/guide/playcore/engage/watch.md +1081 -0
  119. package/skills/android-engage-sdk-integration/references/clusters.md +154 -0
  120. package/skills/android-engage-sdk-integration/references/common.md +519 -0
  121. package/skills/android-engage-sdk-integration/references/patterns.md +527 -0
  122. package/skills/android-engage-sdk-integration/references/requests.md +260 -0
  123. package/skills/android-engage-sdk-integration/references/schemas/food.md +509 -0
  124. package/skills/android-engage-sdk-integration/references/schemas/listen.md +842 -0
  125. package/skills/android-engage-sdk-integration/references/schemas/other.md +220 -0
  126. package/skills/android-engage-sdk-integration/references/schemas/read.md +412 -0
  127. package/skills/android-engage-sdk-integration/references/schemas/shopping.md +357 -0
  128. package/skills/android-engage-sdk-integration/references/schemas/social.md +228 -0
  129. package/skills/android-engage-sdk-integration/references/schemas/travel.md +923 -0
  130. package/skills/android-engage-sdk-integration/references/schemas/tv.md +1226 -0
  131. package/skills/android-engage-sdk-integration/references/schemas/watch.md +1137 -0
  132. package/skills/android-engage-sdk-integration/references/troubleshooting.md +39 -0
  133. package/skills/android-gradle-build-debug/SKILL.md +71 -0
  134. package/skills/android-intent-security/SKILL.md +550 -0
  135. package/skills/android-leanback-to-compose-tv-migration/SKILL.md +743 -0
  136. package/skills/android-leanback-to-compose-tv-migration/references/android/training/tv/get-started/navigation.md +372 -0
  137. package/skills/android-leanback-to-compose-tv-migration/references/android/training/tv/playback/compose/browse.md +243 -0
  138. package/skills/android-leanback-to-compose-tv-migration/references/android/training/tv/playback/compose/index.md +153 -0
  139. package/skills/android-media3-cast-integration/SKILL.md +236 -0
  140. package/skills/android-media3-cast-integration/references/android/media/media3/cast/create-castplayer.md +390 -0
  141. package/skills/android-media3-cast-integration/references/android/media/media3/cast/customize-castoptions.md +93 -0
  142. package/skills/android-media3-cast-integration/references/android/media/media3/cast/index.md +21 -0
  143. package/skills/android-migrate-xml-views-to-jetpack-compose/SKILL.md +127 -0
  144. package/skills/android-migrate-xml-views-to-jetpack-compose/references/analysis-of-the-project-and-layout.md +42 -0
  145. package/skills/android-migrate-xml-views-to-jetpack-compose/references/android/develop/ui/compose/designsystems/migrate-xml-theme-to-compose.md +171 -0
  146. package/skills/android-migrate-xml-views-to-jetpack-compose/references/android/develop/ui/compose/migrate/interoperability-apis/compose-in-views.md +299 -0
  147. package/skills/android-migrate-xml-views-to-jetpack-compose/references/android/develop/ui/compose/migrate/interoperability-apis/views-in-compose.md +286 -0
  148. package/skills/android-migrate-xml-views-to-jetpack-compose/references/android/develop/ui/compose/setup-compose-dependencies-and-compiler.md +197 -0
  149. package/skills/android-migrate-xml-views-to-jetpack-compose/references/identify-optimal-xml-candidate.md +31 -0
  150. package/skills/android-migrate-xml-views-to-jetpack-compose/references/xml-layout-migration.md +86 -0
  151. package/skills/android-ml-kit-genai-prompt-api/SKILL.md +124 -0
  152. package/skills/android-ml-kit-genai-prompt-api/references/get-started.md +272 -0
  153. package/skills/android-ml-kit-genai-prompt-api/references/prefix-caching.md +146 -0
  154. package/skills/android-ml-kit-genai-prompt-api/references/prompt-design.md +55 -0
  155. package/skills/android-ml-kit-genai-prompt-api/references/prompt-optimization.md +74 -0
  156. package/skills/android-ml-kit-genai-prompt-api/references/structured-output.md +219 -0
  157. package/skills/android-ml-kit-genai-prompt-api/references/system-instructions.md +71 -0
  158. package/skills/android-navigation-3/SKILL.md +122 -0
  159. package/skills/android-navigation-3/references/android/guide/navigation/navigation-3/index.md +51 -0
  160. package/skills/android-navigation-3/references/android/guide/navigation/navigation-3/migration-guide.md +670 -0
  161. package/skills/android-navigation-3/references/android/guide/navigation/navigation-3/recipes/animations.md +147 -0
  162. package/skills/android-navigation-3/references/android/guide/navigation/navigation-3/recipes/basic.md +89 -0
  163. package/skills/android-navigation-3/references/android/guide/navigation/navigation-3/recipes/basicdsl.md +85 -0
  164. package/skills/android-navigation-3/references/android/guide/navigation/navigation-3/recipes/basicsaveable.md +90 -0
  165. package/skills/android-navigation-3/references/android/guide/navigation/navigation-3/recipes/bottomsheet.md +195 -0
  166. package/skills/android-navigation-3/references/android/guide/navigation/navigation-3/recipes/common-ui.md +200 -0
  167. package/skills/android-navigation-3/references/android/guide/navigation/navigation-3/recipes/conditional-transitions.md +182 -0
  168. package/skills/android-navigation-3/references/android/guide/navigation/navigation-3/recipes/conditional.md +230 -0
  169. package/skills/android-navigation-3/references/android/guide/navigation/navigation-3/recipes/deeplinks-custommatcher.md +176 -0
  170. package/skills/android-navigation-3/references/android/guide/navigation/navigation-3/recipes/deeplinks-staticuri.md +140 -0
  171. package/skills/android-navigation-3/references/android/guide/navigation/navigation-3/recipes/deeplinks-syntheticbackstack.md +184 -0
  172. package/skills/android-navigation-3/references/android/guide/navigation/navigation-3/recipes/dialog.md +107 -0
  173. package/skills/android-navigation-3/references/android/guide/navigation/navigation-3/recipes/lifecycle-owner.md +185 -0
  174. package/skills/android-navigation-3/references/android/guide/navigation/navigation-3/recipes/material-listdetail.md +141 -0
  175. package/skills/android-navigation-3/references/android/guide/navigation/navigation-3/recipes/material-supportingpane.md +145 -0
  176. package/skills/android-navigation-3/references/android/guide/navigation/navigation-3/recipes/modular-hilt.md +283 -0
  177. package/skills/android-navigation-3/references/android/guide/navigation/navigation-3/recipes/modular-koin.md +287 -0
  178. package/skills/android-navigation-3/references/android/guide/navigation/navigation-3/recipes/multiple-backstacks.md +468 -0
  179. package/skills/android-navigation-3/references/android/guide/navigation/navigation-3/recipes/passingarguments.md +371 -0
  180. package/skills/android-navigation-3/references/android/guide/navigation/navigation-3/recipes/results-event.md +273 -0
  181. package/skills/android-navigation-3/references/android/guide/navigation/navigation-3/recipes/results-state.md +266 -0
  182. package/skills/android-navigation-3/references/android/guide/navigation/navigation-3/recipes/scenes-listdetail.md +435 -0
  183. package/skills/android-navigation-3/references/android/guide/navigation/navigation-3/recipes/scenes-twopane.md +244 -0
  184. package/skills/android-navigation-3/references/android/guide/navigation/type-safe-destinations.md +129 -0
  185. package/skills/android-navigation-event/SKILL.md +312 -0
  186. package/skills/android-navigation-event/references/android/guide/navigation/navigation-event/dispatcher.md +134 -0
  187. package/skills/android-navigation-event/references/android/guide/navigation/navigation-event/handle-back.md +217 -0
  188. package/skills/android-navigation-event/references/android/guide/navigation/navigation-event/index.md +83 -0
  189. package/skills/android-navigation-event/references/android/guide/navigation/navigation-event/setup.md +32 -0
  190. package/skills/android-play-billing-library-version-upgrade/SKILL.md +96 -0
  191. package/skills/android-play-billing-library-version-upgrade/references/android/google/play/billing/release-notes.md +1240 -0
  192. package/skills/android-play-billing-library-version-upgrade/references/migration-logic.md +78 -0
  193. package/skills/android-play-billing-library-version-upgrade/references/version-checklist.md +54 -0
  194. package/skills/android-play-policy-insights/SKILL.md +172 -0
  195. package/skills/android-play-policy-insights/resources/common_mandates.md +100 -0
  196. package/skills/android-play-policy-insights/resources/compliance_report_template.md +59 -0
  197. package/skills/android-play-policy-insights/resources/critic.md +86 -0
  198. package/skills/android-play-policy-insights/resources/goal_data_safety.md +212 -0
  199. package/skills/android-play-policy-insights/resources/goal_permissions_and_apis.md +459 -0
  200. package/skills/android-play-policy-insights/resources/goal_user_account.md +106 -0
  201. package/skills/android-play-policy-insights/resources/policies.json +321 -0
  202. package/skills/android-play-policy-insights/resources/scanner_config.json +843 -0
  203. package/skills/android-play-policy-insights/scripts/generate_report.py +860 -0
  204. package/skills/android-play-policy-insights/scripts/orchestrator.py +1313 -0
  205. package/skills/android-play-policy-insights/scripts/play_store_scraper.py +410 -0
  206. package/skills/android-play-policy-insights/scripts/scanner.py +261 -0
  207. package/skills/android-play-policy-insights/scripts/template_engine.py +243 -0
  208. package/skills/android-profiler/SKILL.md +60 -0
  209. package/skills/android-profiler/analysis/analysis_orchestrator.md +32 -0
  210. package/skills/android-profiler/analysis/workflows/perfetto-sql/perfetto_sql.md +28 -0
  211. package/skills/android-profiler/analysis/workflows/perfetto-trace-analysis/perfetto_trace_analysis.md +121 -0
  212. package/skills/android-profiler/analysis/workflows/perfetto-trace-analysis/references/guiding_principles.md +51 -0
  213. package/skills/android-profiler/analysis/workflows/perfetto-trace-analysis/references/hints/domain_hints_template.md +7 -0
  214. package/skills/android-profiler/analysis/workflows/perfetto-trace-analysis/references/hints/subsystems/hints_cpu.md +56 -0
  215. package/skills/android-profiler/analysis/workflows/perfetto-trace-analysis/references/hints/subsystems/hints_graphics.md +51 -0
  216. package/skills/android-profiler/analysis/workflows/perfetto-trace-analysis/references/hints/subsystems/hints_io.md +46 -0
  217. package/skills/android-profiler/analysis/workflows/perfetto-trace-analysis/references/hints/subsystems/hints_ipc.md +41 -0
  218. package/skills/android-profiler/analysis/workflows/perfetto-trace-analysis/references/hints/subsystems/hints_memory.md +55 -0
  219. package/skills/android-profiler/analysis/workflows/perfetto-trace-analysis/references/hints/subsystems/hints_power.md +33 -0
  220. package/skills/android-profiler/analysis/workflows/perfetto-trace-analysis/references/per_candidate_analysis.md +172 -0
  221. package/skills/android-profiler/analysis/workflows/perfetto-trace-analysis/references/triage.md +94 -0
  222. package/skills/android-profiler/recording/recording_orchestrator.md +36 -0
  223. package/skills/android-profiler/recording/workflows/perfetto-trace-recording/perfetto_trace_recording.md +148 -0
  224. package/skills/android-profiler/recording/workflows/perfetto-trace-recording/references/example-configs/app_jank.pftxt +43 -0
  225. package/skills/android-profiler/recording/workflows/perfetto-trace-recording/references/example-configs/cpu_profile.pftxt +35 -0
  226. package/skills/android-profiler/recording/workflows/perfetto-trace-recording/references/example-configs/java_heap_dump.pftxt +21 -0
  227. package/skills/android-profiler/recording/workflows/perfetto-trace-recording/references/example-configs/long_background.pftxt +37 -0
  228. package/skills/android-profiler/recording/workflows/perfetto-trace-recording/references/example-configs/memory_counters.pftxt +45 -0
  229. package/skills/android-profiler/recording/workflows/perfetto-trace-recording/references/example-configs/native_heap.pftxt +21 -0
  230. package/skills/android-profiler/recording/workflows/perfetto-trace-recording/references/example-configs/sched_cpu.pftxt +33 -0
  231. package/skills/android-profiler/recording/workflows/perfetto-trace-recording/references/trace_config_reference.md +102 -0
  232. package/skills/android-profiler/references/env_setup.md +15 -0
  233. package/skills/android-profiler/references/perfetto/setup.md +29 -0
  234. package/skills/android-profiler/references/perfetto/sql.md +327 -0
  235. package/skills/android-r8-analyzer/SKILL.md +72 -0
  236. package/skills/android-r8-analyzer/references/CONFIGURATION-ANALYZER.md +287 -0
  237. package/skills/android-r8-analyzer/references/CONFIGURATION.md +44 -0
  238. package/skills/android-r8-analyzer/references/KEEP-RULES-IMPACT-HIERARCHY.md +83 -0
  239. package/skills/android-r8-analyzer/references/REDUNDANT-RULES.md +222 -0
  240. package/skills/android-r8-analyzer/references/REFLECTION-GUIDE.md +139 -0
  241. package/skills/android-r8-analyzer/references/REPORT_FORMAT.md +51 -0
  242. package/skills/android-r8-analyzer/references/android/topic/performance/app-optimization/enable-app-optimization.md +252 -0
  243. package/skills/android-r8-analyzer/references/android/training/testing/other-components/ui-automator.md +312 -0
  244. package/skills/android-restore-credentials/SKILL.md +359 -0
  245. package/skills/android-restore-credentials/references/android/guide/topics/manifest/application-element.md +832 -0
  246. package/skills/android-restore-credentials/references/android/identity/passkeys/create-passkeys.md +327 -0
  247. package/skills/android-restore-credentials/references/android/identity/passkeys/sign-in-with-passkeys.md +219 -0
  248. package/skills/android-styles/SKILL.md +229 -0
  249. package/skills/android-styles/references/android/develop/ui/compose/designsystems/custom.md +459 -0
  250. package/skills/android-styles/references/android/develop/ui/compose/styles/fundamentals.md +421 -0
  251. package/skills/android-styles/references/android/develop/ui/compose/styles/state-animations.md +461 -0
  252. package/skills/android-styles/references/android/develop/ui/compose/styles/styles-vs-modifiers.md +48 -0
  253. package/skills/android-styles/references/android/develop/ui/compose/styles/theming.md +269 -0
  254. package/skills/android-verified-email/SKILL.md +432 -0
  255. package/skills/android-verified-email/references/android/identity/credential-manager/index.md +67 -0
  256. package/skills/android-verified-email/references/android/identity/digital-credentials/credential-verifier.md +166 -0
  257. package/skills/android-verified-email/references/android/identity/digital-credentials/email-verification-implementation.md +313 -0
  258. package/skills/android-verified-email/references/android/identity/digital-credentials/email-verification.md +158 -0
  259. package/skills/android-verified-email/references/android/identity/digital-credentials/index.md +112 -0
  260. package/skills/android-verified-email/references/android/identity/passkeys/create-passkeys.md +327 -0
  261. package/skills/android-verified-email/references/android/identity/sign-in/credential-manager-webview.md +84 -0
  262. package/skills/android-wear-compose-m3/SKILL.md +365 -0
  263. package/skills/android-wear-compose-m3/references/android/training/wearables/compose/migrate-to-material3.md +677 -0
  264. package/skills/android-wear-compose-m3/references/foundation/AmbientModeSample.kt.md +123 -0
  265. package/skills/android-wear-compose-m3/references/foundation/AmbientModeSample.kt.md.txt +123 -0
  266. package/skills/android-wear-compose-m3/references/foundation/CurvedWorldSample.kt.md +430 -0
  267. package/skills/android-wear-compose-m3/references/foundation/CurvedWorldSample.kt.md.txt +430 -0
  268. package/skills/android-wear-compose-m3/references/foundation/ExpandableSample.kt.md +99 -0
  269. package/skills/android-wear-compose-m3/references/foundation/ExpandableSample.kt.md.txt +99 -0
  270. package/skills/android-wear-compose-m3/references/foundation/HierarchicalFocusSample.kt.md +141 -0
  271. package/skills/android-wear-compose-m3/references/foundation/HierarchicalFocusSample.kt.md.txt +141 -0
  272. package/skills/android-wear-compose-m3/references/foundation/PagerSamples.kt.md +56 -0
  273. package/skills/android-wear-compose-m3/references/foundation/PagerSamples.kt.md.txt +56 -0
  274. package/skills/android-wear-compose-m3/references/foundation/RotarySamples.kt.md +153 -0
  275. package/skills/android-wear-compose-m3/references/foundation/RotarySamples.kt.md.txt +153 -0
  276. package/skills/android-wear-compose-m3/references/foundation/ScalingLazyColumnSample.kt.md +131 -0
  277. package/skills/android-wear-compose-m3/references/foundation/ScalingLazyColumnSample.kt.md.txt +131 -0
  278. package/skills/android-wear-compose-m3/references/foundation/SwipeToDismissBoxSample.kt.md +169 -0
  279. package/skills/android-wear-compose-m3/references/foundation/SwipeToDismissBoxSample.kt.md.txt +169 -0
  280. package/skills/android-wear-compose-m3/references/foundation/SwipeToRevealSample.kt.md +282 -0
  281. package/skills/android-wear-compose-m3/references/foundation/SwipeToRevealSample.kt.md.txt +282 -0
  282. package/skills/android-wear-compose-m3/references/foundation/TransformingLazyColumnSample.kt.md +335 -0
  283. package/skills/android-wear-compose-m3/references/foundation/TransformingLazyColumnSample.kt.md.txt +335 -0
  284. package/skills/android-wear-compose-m3/references/material3/AlertDialogSample.kt.md +377 -0
  285. package/skills/android-wear-compose-m3/references/material3/AlertDialogSample.kt.md.txt +377 -0
  286. package/skills/android-wear-compose-m3/references/material3/AnimatedTextSample.kt.md +165 -0
  287. package/skills/android-wear-compose-m3/references/material3/AnimatedTextSample.kt.md.txt +165 -0
  288. package/skills/android-wear-compose-m3/references/material3/ButtonGroupSample.kt.md +91 -0
  289. package/skills/android-wear-compose-m3/references/material3/ButtonGroupSample.kt.md.txt +91 -0
  290. package/skills/android-wear-compose-m3/references/material3/ButtonSample.kt.md +496 -0
  291. package/skills/android-wear-compose-m3/references/material3/ButtonSample.kt.md.txt +496 -0
  292. package/skills/android-wear-compose-m3/references/material3/CardSample.kt.md +470 -0
  293. package/skills/android-wear-compose-m3/references/material3/CardSample.kt.md.txt +470 -0
  294. package/skills/android-wear-compose-m3/references/material3/CheckboxButtonSample.kt.md +67 -0
  295. package/skills/android-wear-compose-m3/references/material3/CheckboxButtonSample.kt.md.txt +67 -0
  296. package/skills/android-wear-compose-m3/references/material3/ConfirmationDialogSample.kt.md +162 -0
  297. package/skills/android-wear-compose-m3/references/material3/ConfirmationDialogSample.kt.md.txt +162 -0
  298. package/skills/android-wear-compose-m3/references/material3/CurvedTextSamples.kt.md +78 -0
  299. package/skills/android-wear-compose-m3/references/material3/CurvedTextSamples.kt.md.txt +78 -0
  300. package/skills/android-wear-compose-m3/references/material3/DatePickerSample.kt.md +131 -0
  301. package/skills/android-wear-compose-m3/references/material3/DatePickerSample.kt.md.txt +131 -0
  302. package/skills/android-wear-compose-m3/references/material3/DynamicColorSchemeSample.kt.md +74 -0
  303. package/skills/android-wear-compose-m3/references/material3/DynamicColorSchemeSample.kt.md.txt +74 -0
  304. package/skills/android-wear-compose-m3/references/material3/EdgeButtonSample.kt.md +63 -0
  305. package/skills/android-wear-compose-m3/references/material3/EdgeButtonSample.kt.md.txt +63 -0
  306. package/skills/android-wear-compose-m3/references/material3/FadingExpandingLabelSample.kt.md +60 -0
  307. package/skills/android-wear-compose-m3/references/material3/FadingExpandingLabelSample.kt.md.txt +60 -0
  308. package/skills/android-wear-compose-m3/references/material3/IconButtonSample.kt.md +125 -0
  309. package/skills/android-wear-compose-m3/references/material3/IconButtonSample.kt.md.txt +125 -0
  310. package/skills/android-wear-compose-m3/references/material3/IconToggleButtonSample.kt.md +116 -0
  311. package/skills/android-wear-compose-m3/references/material3/IconToggleButtonSample.kt.md.txt +116 -0
  312. package/skills/android-wear-compose-m3/references/material3/LevelIndicatorSample.kt.md +68 -0
  313. package/skills/android-wear-compose-m3/references/material3/LevelIndicatorSample.kt.md.txt +68 -0
  314. package/skills/android-wear-compose-m3/references/material3/LinearProgressIndicatorSample.kt.md +50 -0
  315. package/skills/android-wear-compose-m3/references/material3/LinearProgressIndicatorSample.kt.md.txt +50 -0
  316. package/skills/android-wear-compose-m3/references/material3/ListHeaderSample.kt.md +177 -0
  317. package/skills/android-wear-compose-m3/references/material3/ListHeaderSample.kt.md.txt +177 -0
  318. package/skills/android-wear-compose-m3/references/material3/OneHandedGestureSamples.kt.md +651 -0
  319. package/skills/android-wear-compose-m3/references/material3/OneHandedGestureSamples.kt.md.txt +651 -0
  320. package/skills/android-wear-compose-m3/references/material3/OpenOnPhoneDialogSample.kt.md +57 -0
  321. package/skills/android-wear-compose-m3/references/material3/OpenOnPhoneDialogSample.kt.md.txt +57 -0
  322. package/skills/android-wear-compose-m3/references/material3/PageIndicatorSample.kt.md +110 -0
  323. package/skills/android-wear-compose-m3/references/material3/PageIndicatorSample.kt.md.txt +110 -0
  324. package/skills/android-wear-compose-m3/references/material3/PagerScaffoldSample.kt.md +204 -0
  325. package/skills/android-wear-compose-m3/references/material3/PagerScaffoldSample.kt.md.txt +204 -0
  326. package/skills/android-wear-compose-m3/references/material3/PickerGroupSample.kt.md +139 -0
  327. package/skills/android-wear-compose-m3/references/material3/PickerGroupSample.kt.md.txt +139 -0
  328. package/skills/android-wear-compose-m3/references/material3/PickerSample.kt.md +111 -0
  329. package/skills/android-wear-compose-m3/references/material3/PickerSample.kt.md.txt +111 -0
  330. package/skills/android-wear-compose-m3/references/material3/PlaceholderSample.kt.md +184 -0
  331. package/skills/android-wear-compose-m3/references/material3/PlaceholderSample.kt.md.txt +184 -0
  332. package/skills/android-wear-compose-m3/references/material3/ProgressIndicatorSample.kt.md +263 -0
  333. package/skills/android-wear-compose-m3/references/material3/ProgressIndicatorSample.kt.md.txt +263 -0
  334. package/skills/android-wear-compose-m3/references/material3/RadioButtonSample.kt.md +105 -0
  335. package/skills/android-wear-compose-m3/references/material3/RadioButtonSample.kt.md.txt +105 -0
  336. package/skills/android-wear-compose-m3/references/material3/ScaffoldSample.kt.md +146 -0
  337. package/skills/android-wear-compose-m3/references/material3/ScaffoldSample.kt.md.txt +146 -0
  338. package/skills/android-wear-compose-m3/references/material3/ScrollAwaySample.kt.md +97 -0
  339. package/skills/android-wear-compose-m3/references/material3/ScrollAwaySample.kt.md.txt +97 -0
  340. package/skills/android-wear-compose-m3/references/material3/ScrollIndicatorSample.kt.md +66 -0
  341. package/skills/android-wear-compose-m3/references/material3/ScrollIndicatorSample.kt.md.txt +66 -0
  342. package/skills/android-wear-compose-m3/references/material3/SliderSample.kt.md +86 -0
  343. package/skills/android-wear-compose-m3/references/material3/SliderSample.kt.md.txt +86 -0
  344. package/skills/android-wear-compose-m3/references/material3/StepperSample.kt.md +148 -0
  345. package/skills/android-wear-compose-m3/references/material3/StepperSample.kt.md.txt +148 -0
  346. package/skills/android-wear-compose-m3/references/material3/SurfaceTransformationSample.kt.md +166 -0
  347. package/skills/android-wear-compose-m3/references/material3/SurfaceTransformationSample.kt.md.txt +166 -0
  348. package/skills/android-wear-compose-m3/references/material3/SwipeToDismissBoxSample.kt.md +172 -0
  349. package/skills/android-wear-compose-m3/references/material3/SwipeToDismissBoxSample.kt.md.txt +172 -0
  350. package/skills/android-wear-compose-m3/references/material3/SwipeToRevealSample.kt.md +367 -0
  351. package/skills/android-wear-compose-m3/references/material3/SwipeToRevealSample.kt.md.txt +367 -0
  352. package/skills/android-wear-compose-m3/references/material3/SwitchButtonSample.kt.md +66 -0
  353. package/skills/android-wear-compose-m3/references/material3/SwitchButtonSample.kt.md.txt +66 -0
  354. package/skills/android-wear-compose-m3/references/material3/TextButtonSample.kt.md +115 -0
  355. package/skills/android-wear-compose-m3/references/material3/TextButtonSample.kt.md.txt +115 -0
  356. package/skills/android-wear-compose-m3/references/material3/TextToggleButtonSample.kt.md +71 -0
  357. package/skills/android-wear-compose-m3/references/material3/TextToggleButtonSample.kt.md.txt +71 -0
  358. package/skills/android-wear-compose-m3/references/material3/TimePickerSample.kt.md +151 -0
  359. package/skills/android-wear-compose-m3/references/material3/TimePickerSample.kt.md.txt +151 -0
  360. package/skills/android-wear-compose-m3/references/material3/TimeTextSample.kt.md +65 -0
  361. package/skills/android-wear-compose-m3/references/material3/TimeTextSample.kt.md.txt +65 -0
  362. package/skills/android-wear-compose-m3/references/material3/TransformationSpecSample.kt.md +246 -0
  363. package/skills/android-wear-compose-m3/references/material3/TransformationSpecSample.kt.md.txt +246 -0
  364. package/skills/android-wear-compose-m3/references/material3/TransformingLazyColumnNotificationsSample.kt.md +89 -0
  365. package/skills/android-wear-compose-m3/references/material3/TransformingLazyColumnNotificationsSample.kt.md.txt +89 -0
  366. package/skills/android-wear-compose-m3/references/material3/TransformingLazyColumnSample.kt.md +309 -0
  367. package/skills/android-wear-compose-m3/references/material3/TransformingLazyColumnSample.kt.md.txt +309 -0
  368. package/skills/android-wear-compose-m3/references/navigation3/SwipeDismissableSceneStrategySample.kt.md +205 -0
  369. package/skills/android-wear-compose-m3/references/navigation3/SwipeDismissableSceneStrategySample.kt.md.txt +205 -0
  370. package/skills/{architecture-feature-first → flutter-architecture-feature-first}/SKILL.md +1 -1
  371. package/skills/{bloc → flutter-bloc}/SKILL.md +1 -1
  372. package/skills/flutter-build-debug/SKILL.md +66 -0
  373. package/skills/{code-review → flutter-code-review}/SKILL.md +1 -1
  374. package/skills/{dart-3-updates → flutter-dart-3-updates}/SKILL.md +1 -1
  375. package/skills/{dart-fix-runtime-errors → flutter-dart-fix-runtime-errors}/SKILL.md +1 -1
  376. package/skills/{dart-resolve-package-conflicts → flutter-dart-resolve-package-conflicts}/SKILL.md +1 -1
  377. package/skills/{dart-run-static-analysis → flutter-dart-run-static-analysis}/SKILL.md +1 -1
  378. package/skills/{dart-use-pattern-matching → flutter-dart-use-pattern-matching}/SKILL.md +1 -1
  379. package/skills/{effective-dart → flutter-effective-dart}/SKILL.md +1 -1
  380. package/skills/{provider → flutter-provider}/SKILL.md +1 -1
  381. package/skills/{riverpod → flutter-riverpod}/SKILL.md +1 -1
  382. package/skills/ios-cocoapods-debug/SKILL.md +65 -0
  383. package/skills/ios-code-review/SKILL.md +56 -0
  384. package/skills/ios-xcode-build-debug/SKILL.md +66 -0
  385. package/skills/{detect-mobile-stack → mobile-detect-stack}/SKILL.md +1 -1
  386. package/skills/mobile-firebase/SKILL.md +54 -0
  387. package/skills/mobile-firebase/references/android/ai-logic.md +31 -0
  388. package/skills/mobile-firebase/references/android/analytics.md +33 -0
  389. package/skills/mobile-firebase/references/android/app-check.md +36 -0
  390. package/skills/mobile-firebase/references/android/auth.md +44 -0
  391. package/skills/mobile-firebase/references/android/crashlytics.md +31 -0
  392. package/skills/mobile-firebase/references/android/firestore.md +44 -0
  393. package/skills/mobile-firebase/references/android/functions.md +33 -0
  394. package/skills/mobile-firebase/references/android/in-app-messaging.md +28 -0
  395. package/skills/mobile-firebase/references/android/messaging.md +41 -0
  396. package/skills/mobile-firebase/references/android/realtime-database.md +50 -0
  397. package/skills/mobile-firebase/references/android/remote-config.md +43 -0
  398. package/skills/mobile-firebase/references/android/sql-connect.md +31 -0
  399. package/skills/mobile-firebase/references/android/storage.md +39 -0
  400. package/skills/mobile-firebase/references/android.md +30 -0
  401. package/skills/{firebase-ai/SKILL.md → mobile-firebase/references/flutter/ai-logic.md} +2 -8
  402. package/skills/{firebase-analytics/SKILL.md → mobile-firebase/references/flutter/analytics.md} +2 -8
  403. package/skills/{firebase-app-check/SKILL.md → mobile-firebase/references/flutter/app-check.md} +2 -8
  404. package/skills/{firebase-auth/SKILL.md → mobile-firebase/references/flutter/auth.md} +2 -8
  405. package/skills/{firebase-crashlytics/SKILL.md → mobile-firebase/references/flutter/crashlytics.md} +2 -8
  406. package/skills/{firebase-cloud-firestore/SKILL.md → mobile-firebase/references/flutter/firestore.md} +2 -8
  407. package/skills/{firebase-cloud-functions/SKILL.md → mobile-firebase/references/flutter/functions.md} +2 -8
  408. package/skills/{firebase-in-app-messaging/SKILL.md → mobile-firebase/references/flutter/in-app-messaging.md} +2 -8
  409. package/skills/{firebase-messaging/SKILL.md → mobile-firebase/references/flutter/messaging.md} +2 -8
  410. package/skills/{firebase-database/SKILL.md → mobile-firebase/references/flutter/realtime-database.md} +2 -8
  411. package/skills/{firebase-remote-config/SKILL.md → mobile-firebase/references/flutter/remote-config.md} +2 -8
  412. package/skills/{flutterfire-configure/SKILL.md → mobile-firebase/references/flutter/setup-flutterfire.md} +1 -8
  413. package/skills/{firebase-data-connect/SKILL.md → mobile-firebase/references/flutter/sql-connect.md} +2 -8
  414. package/skills/{firebase-storage/SKILL.md → mobile-firebase/references/flutter/storage.md} +2 -8
  415. package/skills/mobile-firebase/references/flutter.md +36 -0
  416. package/skills/mobile-firebase/references/ios/ai-logic.md +30 -0
  417. package/skills/mobile-firebase/references/ios/analytics.md +33 -0
  418. package/skills/mobile-firebase/references/ios/app-check.md +36 -0
  419. package/skills/mobile-firebase/references/ios/auth.md +48 -0
  420. package/skills/mobile-firebase/references/ios/crashlytics.md +34 -0
  421. package/skills/mobile-firebase/references/ios/firestore.md +53 -0
  422. package/skills/mobile-firebase/references/ios/functions.md +35 -0
  423. package/skills/mobile-firebase/references/ios/in-app-messaging.md +26 -0
  424. package/skills/mobile-firebase/references/ios/messaging.md +45 -0
  425. package/skills/mobile-firebase/references/ios/realtime-database.md +49 -0
  426. package/skills/mobile-firebase/references/ios/remote-config.md +44 -0
  427. package/skills/mobile-firebase/references/ios/sql-connect.md +33 -0
  428. package/skills/mobile-firebase/references/ios/storage.md +36 -0
  429. package/skills/mobile-firebase/references/ios.md +28 -0
  430. package/skills/mobile-firebase/references/react-native/ai-logic.md +32 -0
  431. package/skills/mobile-firebase/references/react-native/analytics.md +43 -0
  432. package/skills/mobile-firebase/references/react-native/app-check.md +35 -0
  433. package/skills/mobile-firebase/references/react-native/auth.md +50 -0
  434. package/skills/mobile-firebase/references/react-native/crashlytics.md +36 -0
  435. package/skills/mobile-firebase/references/react-native/firestore.md +45 -0
  436. package/skills/mobile-firebase/references/react-native/functions.md +28 -0
  437. package/skills/mobile-firebase/references/react-native/in-app-messaging.md +27 -0
  438. package/skills/mobile-firebase/references/react-native/messaging.md +46 -0
  439. package/skills/mobile-firebase/references/react-native/realtime-database.md +46 -0
  440. package/skills/mobile-firebase/references/react-native/remote-config.md +32 -0
  441. package/skills/mobile-firebase/references/react-native/sql-connect.md +11 -0
  442. package/skills/mobile-firebase/references/react-native/storage.md +30 -0
  443. package/skills/mobile-firebase/references/react-native.md +29 -0
  444. package/skills/mobile-test/SKILL.md +63 -0
  445. package/skills/mobile-test/references/android/setup/GUIDE.md +183 -0
  446. package/skills/mobile-test/references/android/setup/references/android/develop/ui/compose/testing/common-patterns.md +181 -0
  447. package/skills/mobile-test/references/android/setup/references/android/studio/preview/compose-screenshot-testing.md +255 -0
  448. package/skills/mobile-test/references/android/setup/references/android/training/dependency-injection/hilt-testing.md +447 -0
  449. package/skills/mobile-test/references/android.md +83 -0
  450. package/skills/{dart-collect-coverage/SKILL.md → mobile-test/references/flutter/coverage.md} +2 -11
  451. package/skills/{dart-generate-test-mocks/SKILL.md → mobile-test/references/flutter/generate-mocks.md} +2 -11
  452. package/skills/{flutter-add-integration-test/SKILL.md → mobile-test/references/flutter/integration-tests.md} +2 -11
  453. package/skills/{dart-migrate-to-checks-package/SKILL.md → mobile-test/references/flutter/migrate-to-checks.md} +2 -13
  454. package/skills/{mockito/SKILL.md → mobile-test/references/flutter/mockito.md} +1 -8
  455. package/skills/{mocktail/SKILL.md → mobile-test/references/flutter/mocktail.md} +1 -8
  456. package/skills/{patrol-e2e-testing/SKILL.md → mobile-test/references/flutter/patrol.md} +1 -8
  457. package/skills/{testing/SKILL.md → mobile-test/references/flutter/testing-guidelines.md} +1 -8
  458. package/skills/{dart-add-unit-test/SKILL.md → mobile-test/references/flutter/unit-tests.md} +2 -11
  459. package/skills/{flutter-add-widget-test/SKILL.md → mobile-test/references/flutter/widget-tests.md} +2 -11
  460. package/skills/mobile-test/references/flutter.md +44 -0
  461. package/skills/mobile-test/references/ios.md +79 -0
  462. package/skills/mobile-test/references/react-native.md +62 -0
  463. /package/skills/{dart-use-pattern-matching → flutter-dart-use-pattern-matching}/examples/json_patterns.dart +0 -0
@@ -0,0 +1,244 @@
1
+ # Two-Pane Scene Recipe
2
+
3
+ This example shows how to create a two pane layout using the Scenes API.
4
+
5
+ A `TwoPaneSceneStrategy` will return a `TwoPaneScene` if:
6
+
7
+ - the window width is over 600dp
8
+ - the last two nav entries on the back stack have indicated that they support being displayed in a `TwoPaneScene` in their metadata.
9
+
10
+ See `TwoPaneScene.kt` for more implementation details.
11
+ [![](https://developer.android.com/static/images/picto-icons/code.svg) Explore View the full recipe on GitHub.](https://github.com/android/nav3-recipes/tree/main/app/src/main/java/com/example/nav3recipes/scenes/twopane)
12
+
13
+ ```
14
+ package com.example.nav3recipes.scenes.twopane
15
+
16
+ import androidx.compose.foundation.layout.Column
17
+ import androidx.compose.foundation.layout.Row
18
+ import androidx.compose.foundation.layout.fillMaxSize
19
+ import androidx.compose.material3.adaptive.currentWindowAdaptiveInfoV2
20
+ import androidx.compose.runtime.Composable
21
+ import androidx.compose.runtime.remember
22
+ import androidx.compose.ui.Modifier
23
+ import androidx.navigation3.runtime.NavEntry
24
+ import androidx.navigation3.runtime.NavMetadataKey
25
+ import androidx.navigation3.runtime.contains
26
+ import androidx.navigation3.runtime.metadata
27
+ import androidx.navigation3.scene.Scene
28
+ import androidx.navigation3.scene.SceneStrategy
29
+ import androidx.navigation3.scene.SceneStrategyScope
30
+ import androidx.window.core.layout.WindowSizeClass
31
+ import androidx.window.core.layout.WindowSizeClass.Companion.WIDTH_DP_MEDIUM_LOWER_BOUND
32
+
33
+ // --- TwoPaneScene ---
34
+ /**
35
+ * A custom [Scene] that displays two [NavEntry]s side-by-side in a 50/50 split.
36
+ */
37
+ data class TwoPaneScene<T : Any>(
38
+ override val key: Any,
39
+ override val previousEntries: List<NavEntry<T>>,
40
+ val firstEntry: NavEntry<T>,
41
+ val secondEntry: NavEntry<T>
42
+ ) : Scene<T> {
43
+ override val entries: List<NavEntry<T>> = listOf(firstEntry, secondEntry)
44
+ override val content: @Composable (() -> Unit) = {
45
+ Row(modifier = Modifier.fillMaxSize()) {
46
+ Column(modifier = Modifier.weight(0.5f)) {
47
+ firstEntry.Content()
48
+ }
49
+ Column(modifier = Modifier.weight(0.5f)) {
50
+ secondEntry.Content()
51
+ }
52
+ }
53
+ }
54
+
55
+ companion object {
56
+ /**
57
+ * Helper function to add metadata to a [NavEntry] indicating it can be displayed
58
+ * in a two-pane layout.
59
+ */
60
+ fun twoPane() = metadata {
61
+ put(TwoPaneKey, true)
62
+ }
63
+ }
64
+
65
+ object TwoPaneKey : NavMetadataKey<Boolean>
66
+ }
67
+
68
+ @Composable
69
+ fun <T : Any> rememberTwoPaneSceneStrategy(): TwoPaneSceneStrategy<T> {
70
+ val windowSizeClass = currentWindowAdaptiveInfoV2().windowSizeClass
71
+
72
+ return remember(windowSizeClass) {
73
+ TwoPaneSceneStrategy(windowSizeClass)
74
+ }
75
+ }
76
+
77
+
78
+ // --- TwoPaneSceneStrategy ---
79
+ /**
80
+ * A [SceneStrategy] that activates a [TwoPaneScene] if the window is wide enough
81
+ * and the top two back stack entries declare support for two-pane display.
82
+ */
83
+ class TwoPaneSceneStrategy<T : Any>(val windowSizeClass: WindowSizeClass) : SceneStrategy<T> {
84
+
85
+ override fun SceneStrategyScope<T>.calculateScene(entries: List<NavEntry<T>>): Scene<T>? {
86
+
87
+ // Condition 1: Only return a Scene if the window is sufficiently wide to render two panes.
88
+ // We use isWidthAtLeastBreakpoint with WIDTH_DP_MEDIUM_LOWER_BOUND (600dp).
89
+ if (!windowSizeClass.isWidthAtLeastBreakpoint(WIDTH_DP_MEDIUM_LOWER_BOUND)) {
90
+ return null
91
+ }
92
+
93
+ val lastTwoEntries = entries.takeLast(2)
94
+
95
+ // Condition 2: Only return a Scene if there are two entries, and both have declared
96
+ // they can be displayed in a two pane scene.
97
+ return if (lastTwoEntries.size == 2
98
+ && lastTwoEntries.all { it.metadata.contains(TwoPaneScene.TwoPaneKey) }
99
+ ) {
100
+ val firstEntry = lastTwoEntries.first()
101
+ val secondEntry = lastTwoEntries.last()
102
+
103
+ // The scene key must uniquely represent the state of the scene.
104
+ // A Pair of the first and second entry keys ensures uniqueness.
105
+ val sceneKey = Pair(firstEntry.contentKey, secondEntry.contentKey)
106
+
107
+ TwoPaneScene(
108
+ key = sceneKey,
109
+ // Where we go back to is a UX decision. In this case, we only remove the top
110
+ // entry from the back stack, despite displaying two entries in this scene.
111
+ // This is because in this app we only ever add one entry to the
112
+ // back stack at a time. It would therefore be confusing to the user to add one
113
+ // when navigating forward, but remove two when navigating back.
114
+ previousEntries = entries.dropLast(1),
115
+ firstEntry = firstEntry,
116
+ secondEntry = secondEntry
117
+ )
118
+
119
+ } else {
120
+ null
121
+ }
122
+ }
123
+
124
+
125
+ }
126
+ ```
127
+
128
+ ```
129
+ /*
130
+ * Copyright 2025 The Android Open Source Project
131
+ *
132
+ * Licensed under the Apache License, Version 2.0 (the "License");
133
+ * you may not use this file except in compliance with the License.
134
+ * You may obtain a copy of the License at
135
+ *
136
+ * http://www.apache.org/licenses/LICENSE-2.0
137
+ *
138
+ * Unless required by applicable law or agreed to in writing, software
139
+ * distributed under the License is distributed on an "AS IS" BASIS,
140
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
141
+ * See the License for the specific language governing permissions and
142
+ * limitations under the License.
143
+ */
144
+
145
+ package com.example.nav3recipes.scenes.twopane
146
+
147
+ import android.os.Bundle
148
+ import androidx.activity.ComponentActivity
149
+ import androidx.activity.compose.setContent
150
+ import androidx.compose.animation.SharedTransitionLayout
151
+ import androidx.compose.foundation.background
152
+ import androidx.compose.foundation.layout.Column
153
+ import androidx.compose.material3.Button
154
+ import androidx.compose.material3.Text
155
+ import androidx.compose.ui.Alignment
156
+ import androidx.compose.ui.Modifier
157
+ import androidx.lifecycle.compose.dropUnlessResumed
158
+ import androidx.navigation3.runtime.NavBackStack
159
+ import androidx.navigation3.runtime.NavKey
160
+ import androidx.navigation3.runtime.entryProvider
161
+ import androidx.navigation3.runtime.rememberNavBackStack
162
+ import androidx.navigation3.ui.NavDisplay
163
+ import com.example.nav3recipes.content.ContentBase
164
+ import com.example.nav3recipes.content.ContentGreen
165
+ import com.example.nav3recipes.content.ContentRed
166
+ import com.example.nav3recipes.ui.setEdgeToEdgeConfig
167
+ import com.example.nav3recipes.ui.theme.colors
168
+ import kotlinx.serialization.Serializable
169
+
170
+ @Serializable
171
+ private object Home : NavKey
172
+
173
+ @Serializable
174
+ private data class Product(val id: Int) : NavKey
175
+
176
+ @Serializable
177
+ private data object Profile : NavKey
178
+
179
+ class TwoPaneActivity : ComponentActivity() {
180
+
181
+ override fun onCreate(savedInstanceState: Bundle?) {
182
+ setEdgeToEdgeConfig()
183
+ super.onCreate(savedInstanceState)
184
+
185
+ setContent {
186
+ val backStack = rememberNavBackStack(Home)
187
+ val twoPaneStrategy = rememberTwoPaneSceneStrategy<NavKey>()
188
+
189
+ SharedTransitionLayout {
190
+ NavDisplay(
191
+ backStack = backStack,
192
+ onBack = { backStack.removeLastOrNull() },
193
+ sceneStrategies = listOf(twoPaneStrategy),
194
+ sharedTransitionScope = this,
195
+ entryProvider = entryProvider {
196
+ entry<Home>(
197
+ metadata = TwoPaneScene.twoPane()
198
+ ) {
199
+ ContentRed("Welcome to Nav3") {
200
+ Button(onClick = { backStack.addProductRoute(1) }) {
201
+ Text("View the first product")
202
+ }
203
+ }
204
+ }
205
+ entry<Product>(
206
+ metadata = TwoPaneScene.twoPane()
207
+ ) { product ->
208
+ ContentBase(
209
+ "Product ${product.id} ",
210
+ Modifier.background(colors[product.id % colors.size])
211
+ ) {
212
+ Column(horizontalAlignment = Alignment.CenterHorizontally) {
213
+ Button(onClick = dropUnlessResumed {
214
+ backStack.addProductRoute(product.id + 1)
215
+ }) {
216
+ Text("View the next product")
217
+ }
218
+ Button(onClick = dropUnlessResumed {
219
+ backStack.add(Profile)
220
+ }) {
221
+ Text("View profile")
222
+ }
223
+ }
224
+ }
225
+ }
226
+ entry<Profile> {
227
+ ContentGreen("Profile (single pane only)")
228
+ }
229
+ }
230
+ )
231
+ }
232
+ }
233
+ }
234
+ }
235
+
236
+ private fun NavBackStack<NavKey>.addProductRoute(productId: Int) {
237
+ val productRoute =
238
+ Product(productId)
239
+ // Avoid adding the same product route to the back stack twice.
240
+ if (!contains(productRoute)) {
241
+ add(productRoute)
242
+ }
243
+ }
244
+ ```
@@ -0,0 +1,129 @@
1
+ This guide outlines the process of replacing string-based routes with
2
+ serializable Kotlin types to achieve compile-time safety and eliminate runtime
3
+ crashes caused by typos or incorrect argument types.
4
+
5
+ ## Prerequisites
6
+
7
+ Before starting the migration, verify that your project meets the following
8
+ requirements:
9
+
10
+ 1. **Navigation version**: Update to Jetpack Navigation 2.8.0 or higher
11
+ 2. **Kotlin serialization plugin**:
12
+ 3. Add the plugin to `libs.versions.toml`:
13
+
14
+ [libraries]
15
+ kotlinx-serialization-json = { module = "org.jetbrains.kotlinx:kotlinx-serialization-json", version.ref = "kotlinxSerializationJson" }
16
+
17
+ [plugins]
18
+ kotlin-serialization = { id = "org.jetbrains.kotlin.plugin.serialization", version.ref = "kotlin" }
19
+
20
+ - Add the dependencies to your top-level `build.gradle.kts` and module-level `build.gradle.kts`.
21
+
22
+ ## Step 1: Define Your Destinations
23
+
24
+ Replace your constant route strings with `@Serializable` objects and classes.
25
+
26
+ - **For screens without arguments** : Use a `data object`
27
+ - **For screens with arguments** : Use a `data class`
28
+
29
+ **Before (string based):**
30
+
31
+ const val ROUTE_HOME = "home"
32
+ const val ROUTE_PROFILE = "profile/{userId}"
33
+
34
+ **After (type safe):**
35
+
36
+ import kotlinx.serialization.Serializable
37
+
38
+ @Serializable
39
+ object Home
40
+
41
+ @Serializable
42
+ data class Profile(val userId: String)
43
+
44
+ ## Step 2: Update the NavHost Configuration
45
+
46
+ Update your `NavHost` to use the new generic types in the `composable` and
47
+ `dialog` function.
48
+
49
+ **Before:**
50
+
51
+ NavHost(navController, startDestination = "home") {
52
+ composable("home") { HomeScreen(...) }
53
+ composable("profile/{userId}") { backStackEntry ->
54
+ val userId = backStackEntry.arguments?.getString("userId")
55
+ ProfileScreen(userId)
56
+ }
57
+ }
58
+
59
+ **After:**
60
+
61
+ NavHost(navController, startDestination = Home) {
62
+ composable<Home> {
63
+ HomeScreen(...)
64
+ }
65
+ composable<Profile> { backStackEntry ->
66
+ // The library automatically handles argument extraction
67
+ val profile: Profile = backStackEntry.toRoute()
68
+ ProfileScreen(profile.userId)
69
+ }
70
+ }
71
+
72
+ ## Step 3: Implement Type-Safe Navigation Calls
73
+
74
+ Replace string-interpolated navigation calls with class instances.
75
+
76
+ **Before:**
77
+
78
+ navController.navigate("profile/user123")
79
+
80
+ **After:**
81
+
82
+ navController.navigate(Profile(userId = "user123"))
83
+
84
+ ## Step 4: Accessing Arguments in ViewModels
85
+
86
+ If you use a `ViewModel`, you can now extract the route object directly from the
87
+ `SavedStateHandle`.
88
+
89
+ **Implementation:**
90
+
91
+ class ProfileViewModel(
92
+ savedStateHandle: SavedStateHandle
93
+ ) : ViewModel() {
94
+ // Automatically parses arguments into the Profile class
95
+ private val profile = savedStateHandle.toRoute<Profile>()
96
+ val userId = profile.userId
97
+ }
98
+
99
+ ## Step 5: (Advanced) Handling Custom Types
100
+
101
+ If you need to pass complex data classes (not just primitives), you must define
102
+ a custom `NavType`.
103
+
104
+ 1. **Create the Custom Type** : \`\`\`kotlin val SearchFilterType = object : NavType(isNullableAllowed = false) { override fun get(bundle: Bundle, key: String): SearchFilter? = Json.decodeFromString(bundle.getString(key) ?: return null)
105
+
106
+ override fun parseValue(value: String): SearchFilter =
107
+ Json.decodeFromString(Uri.decode(value))
108
+
109
+ override fun put(bundle: Bundle, key: String, value: SearchFilter) {
110
+ bundle.putString(key, Json.encodeToString(value))
111
+ }
112
+
113
+ }
114
+
115
+
116
+
117
+ 2. **Register it in the Graph**:
118
+ ```kotlin
119
+ composable<Search>(
120
+ typeMap = mapOf(typeOf<SearchFilter>() to SearchFilterType)
121
+ ) { ... }
122
+
123
+ ## Best practices and tips
124
+
125
+ - **Sealed Hierarchies**: For large apps, group your routes using a sealed interface or class to keep the navigation structure organized
126
+ - **Object Instances** : For routes without parameters, always use `object` instead of `class` to avoid unnecessary allocations
127
+ - **Nullable Types** : The new API supports nullable types (for example, `data
128
+ class Search(val query: String?)`) and provides default values automatically
129
+ - **Testing** : Use `navController.currentBackStackEntry?.hasRoute<T>()` to check the current destination in a type-safe manner during UI tests
@@ -0,0 +1,312 @@
1
+ ---
2
+ name: android-navigation-event
3
+ description: Intercept back gestures and run Predictive Back animations using the
4
+ NavigationEvent (androidx.navigationevent) library in Compose Android. Handles Activity
5
+ setup, parent-child dispatcher scoping in `ViewPagers` or tabs, Compose `NavigationBackHandler`,
6
+ and migration from legacy `BackHandler` on SDK 36+.
7
+ license: Apache-2.0
8
+ source: https://github.com/android/skills
9
+ routing: manual
10
+ stacks: [android]
11
+ metadata:
12
+ author: Google LLC
13
+ last-updated: '2026-09-01'
14
+ keywords:
15
+ - Android
16
+ - Navigation Event
17
+ - Jetpack Compose
18
+ - Back Navigation
19
+ - Dispatcher
20
+ - Guidelines
21
+ - Troubleshooting
22
+ - ComponentActivity
23
+ - Dialog
24
+ - ViewPager
25
+ ---
26
+
27
+ ## Common guidelines
28
+
29
+ - **For architecture concepts** : To understand the foundational architecture, continuous gesture event lifecycles, or class definitions of the Navigation Event library, read [Navigation Event overview](references/android/guide/navigation/navigation-event/index.md).
30
+ - **For Android target** : If compile SDK is lower than 36, set it to `36` or higher in `build.gradle.kts`.
31
+ - **For Compose Android target**: The project must use Jetpack Compose for Compose-specific APIs. This skill is scoped exclusively to Compose Android (Android Views and non-Compose implementations are excluded).
32
+ - **For activity dispatchers** : `ComponentActivity` automatically implements `NavigationEventDispatcherOwner` out-of-the-box. You must use the built-in `navigationEventDispatcher` without creating anonymous delegate owners or overriding member properties.
33
+ - **For dialog scoping** : Floating windows (Compose `Dialog`, `ModalBottomSheet`, `ComponentDialog`) automatically provide a `NavigationEventDispatcherOwner`. You don't need manual `CompositionLocalProvider` propagation for dialogs.
34
+ - **For parent-child dispatcher hierarchies** : When scoping navigation handling to `ViewPagers`, tabbed interfaces, or nested navigation containers in Compose, use `rememberNavigationEventDispatcherOwner()` to create a child owner linked to the parent. Disabling the owner (`enabled = false`) automatically cascades to disable all child handlers.
35
+ - **For Compose handlers** : A one-to-one relationship between `NavigationEventState` and handlers is strictly enforced. Never bind the same `NavigationEventState` to multiple active `NavigationBackHandler` instances (`IllegalArgumentException`).
36
+
37
+ ## Step 1: Plan
38
+
39
+ To complete this step, you **MUST** ensure the following:
40
+
41
+ 1. **Identify the target platform** : Verify the app is targeting Compose Android. If `compileSdk` is lower than 36, set it to `36` or higher in `build.gradle.kts`.
42
+ 2. **Navigation check**: Check if Navigation 3 is in use. If it is in use, use Navigation 3's built-in back navigation support rather than manually implementing low-level dispatchers from this skill.
43
+ 3. **Hierarchy check** : Identify host Activities, `ViewPagers`, tabbed interfaces, or nested navigation hosts that require back gesture interception or parent-child dispatcher linking.
44
+ 4. **Migration check** : Check if the project is migrating from back handling (`OnBackPressedCallback`, `BackHandler`, `onBackPresser`) to `NavigationEvent` and `NavigationBackHandler`.
45
+ 5. **Input interception** : Detect where the app is intercepting navigation events from gestures or hardware button presses requiring translation to `NavigationEvent`.
46
+
47
+ ## Step 2: Set up dependencies
48
+
49
+ To complete this step, you **MUST** ensure the following:
50
+
51
+ - For setting up compile SDKs, declaring catalog versions, and adding dependencies, follow [setup guide](references/android/guide/navigation/navigation-event/setup.md).
52
+
53
+ ## Step 3: Configure dispatcher and inputs
54
+
55
+ To complete this step, you **MUST** ensure the following:
56
+
57
+ - To configure your dispatcher, leverage automatic `ComponentActivity` or `ComponentDialog` owner resolution.
58
+ - Link parent-child dispatchers in Compose following [dispatcher guide](references/android/guide/navigation/navigation-event/dispatcher.md).
59
+
60
+ ## Step 4: Handle back navigation and UI transitions
61
+
62
+ To complete this step, you **MUST** ensure the following:
63
+
64
+ - To create navigation event handlers, integrate back gesture interception in Compose, animate UI components during swipes, and migrate from legacy back handlers, follow [handle back guide](references/android/guide/navigation/navigation-event/handle-back.md).
65
+
66
+ ## Step 5: Clean up resources
67
+
68
+ > [!WARNING]
69
+ > **Warning:** Compose APIs perform teardown automatically. When using Compose APIs such as `NavigationBackHandler` and `rememberNavigationEventDispatcherOwner()`, handler removal and dispatcher disposal occur automatically when the composable leaves the composition.
70
+
71
+ You **MUST** perform explicit manual cleanup only when managing custom
72
+ dispatchers or non-Compose handlers:
73
+
74
+ - Call `remove()` on active handlers during teardown.
75
+ - Call `isEnabled = false` to temporarily disable navigation subtrees.
76
+ - Call `dispose()` on dispatcher instances when hosting components are destroyed. Disposing a parent dispatcher automatically cascades to all child dispatchers.
77
+
78
+ ## Core troubleshooting guidelines
79
+
80
+ ### 1. Activity dispatcher setup (StackOverflowError recursion)
81
+
82
+ `ComponentActivity` implements `NavigationEventDispatcherOwner` automatically
83
+ out-of-the-box. Don't override `navigationEventDispatcher` or wrap it in an
84
+ anonymous delegate owner.
85
+
86
+ #### RIGHT
87
+
88
+ **Why this is RIGHT** : Compose apps use `ComponentActivity` as the host.
89
+ `LocalNavigationEventDispatcherOwner.current` automatically resolves the
90
+ Activity's built-in dispatcher.
91
+
92
+
93
+ ```kotlin
94
+ // RIGHT
95
+ class MainActivity : ComponentActivity() {
96
+ override fun onCreate(savedInstanceState: Bundle?) {
97
+ super.onCreate(savedInstanceState)
98
+ setContent {
99
+ MyApplicationContent()
100
+ }
101
+ }
102
+ }
103
+ ```
104
+
105
+ <br />
106
+
107
+ #### WRONG
108
+
109
+ **Why this is WRONG** : Implementing `NavigationEventDispatcherOwner` directly on
110
+ `MainActivity` and overriding `navigationEventDispatcher` with a new instance
111
+ shadows the library's extension property, causing a recursive infinite loop
112
+ crash on launch (`StackOverflowError`). Creating redundant anonymous delegate
113
+ owners (`object : NavigationEventDispatcherOwner`) is unnecessary.
114
+
115
+
116
+ ```kotlin
117
+ // WRONG
118
+ class MainActivity : ComponentActivity(), NavigationEventDispatcherOwner {
119
+ override val navigationEventDispatcher = NavigationEventDispatcher() // Shadow loop crash
120
+ override fun onCreate(savedInstanceState: Bundle?) {
121
+ super.onCreate(savedInstanceState)
122
+ setContent {
123
+ MyApplicationContent()
124
+ }
125
+ }
126
+ }
127
+ ```
128
+
129
+ <br />
130
+
131
+ ### 2. Floating window and dialog scoping (automatic ComponentDialog owner)
132
+
133
+ Floating windows (Compose `Dialog`, `ModalBottomSheet`, and any window backed by
134
+ `ComponentDialog`) automatically provide a `NavigationEventDispatcherOwner`.
135
+ Don't manually re-provide `LocalNavigationEventDispatcherOwner` using
136
+ `CompositionLocalProvider` inside dialogs.
137
+
138
+ #### RIGHT
139
+
140
+ **Why this is RIGHT** : `ComponentDialog` handles navigation dispatchers
141
+ automatically. Compose `Dialog` components resolve their dispatcher owner
142
+ out-of-the-box without manual propagation.
143
+
144
+
145
+ ```kotlin
146
+ // RIGHT
147
+ @Composable
148
+ fun MyDialog(onDismiss: () -> Unit) {
149
+ Dialog(onDismissRequest = onDismiss) {
150
+ val navigationState = rememberNavigationEventState(currentInfo = NavigationEventInfo.None)
151
+ NavigationBackHandler(
152
+ state = navigationState,
153
+ onBackCompleted = onDismiss
154
+ )
155
+ }
156
+ }
157
+ ```
158
+
159
+ <br />
160
+
161
+ #### WRONG
162
+
163
+ **Why this is WRONG** : Wrapping dialog content in a manual
164
+ `CompositionLocalProvider` creates redundant boilerplate and obscures the
165
+ automatic dispatcher resolution provided by `ComponentDialog`.
166
+
167
+
168
+ ```kotlin
169
+ // WRONG
170
+ @Composable
171
+ fun MyDialog(onDismiss: () -> Unit) {
172
+ val dispatcherOwner = LocalNavigationEventDispatcherOwner.current!!
173
+ Dialog(onDismissRequest = onDismiss) {
174
+ // Redundant: ComponentDialog provides NavigationEventDispatcherOwner automatically
175
+ CompositionLocalProvider( LocalNavigationEventDispatcherOwner provides dispatcherOwner) {
176
+ val navigationState = rememberNavigationEventState(currentInfo = NavigationEventInfo.None)
177
+ NavigationBackHandler(
178
+ state = navigationState,
179
+ onBackCompleted = onDismiss
180
+ )
181
+ }
182
+ }
183
+ }
184
+ ```
185
+
186
+ <br />
187
+
188
+ ### 3. Parent-child dispatcher hierarchy (`ViewPagers` and nested navigation)
189
+
190
+ When managing nested UI hierarchies such as `ViewPagers`, tabbed
191
+ interfaces, or custom navigation containers in Compose, use
192
+ `rememberNavigationEventDispatcherOwner()` to create a child owner linked to the
193
+ composition hierarchy. Setting `enabled = false` on the child owner
194
+ automatically disables its dispatcher and all registered child handlers.
195
+
196
+ #### RIGHT
197
+
198
+ **Why this is RIGHT** : Using `rememberNavigationEventDispatcherOwner(enabled =
199
+ isSelected)` creates a scoped child dispatcher linked to the parent from
200
+ `LocalNavigationEventDispatcherOwner.current`. Providing it using
201
+ `CompositionLocalProvider` ensures non-visible tabs or pages automatically stop
202
+ intercepting back gestures without leaking handlers.
203
+
204
+
205
+ ```kotlin
206
+ // RIGHT: Scoping child navigation in a ViewPager or Tab interface
207
+ @Composable
208
+ fun TabPage(isSelected: Boolean) {
209
+ val childOwner = rememberNavigationEventDispatcherOwner(enabled = isSelected)
210
+ CompositionLocalProvider(LocalNavigationEventDispatcherOwner provides childOwner) {
211
+ val navigationState = rememberNavigationEventState(currentInfo = NavigationEventInfo.None)
212
+ NavigationBackHandler(
213
+ state = navigationState,
214
+ onBackCompleted = { /* Handle page back navigation */ }
215
+ )
216
+ // Page content
217
+ }
218
+ }
219
+ ```
220
+
221
+ <br />
222
+
223
+ #### WRONG
224
+
225
+ **Why this is WRONG** : Creating unlinked standalone dispatchers, instantiating
226
+ raw dispatchers without remembering them across recompositions, or attempting to
227
+ use non-existent methods like `.addChild()` breaks hierarchy routing and leaves
228
+ child handlers active even when the page is inactive.
229
+
230
+
231
+ ```kotlin
232
+ // WRONG
233
+ @Composable
234
+ fun TabPage(isSelected: Boolean) {
235
+ val parentDispatcher = LocalNavigationEventDispatcherOwner.current?.navigationEventDispatcher
236
+ val childDispatcher = NavigationEventDispatcher() // Unlinked and not remembered across recompositions
237
+ // WRONG: Method does not exist
238
+ parentDispatcher?.addChild(childDispatcher)
239
+ }
240
+ ```
241
+
242
+ <br />
243
+
244
+ ### 4. Compose multi-handler registration (IllegalArgumentException)
245
+
246
+ You must not bind the same `NavigationEventState` to multiple active
247
+ `NavigationBackHandler` instances, as this throws an `IllegalArgumentException`
248
+ at runtime. To handle conditional workflows (such as checking for unsaved
249
+ changes versus navigating back immediately), you must register a single unified
250
+ handler and branch logic inside `onBackCompleted`.
251
+
252
+ #### RIGHT
253
+
254
+ **Why this is RIGHT** : Using a single `NavigationBackHandler` with internal
255
+ branching logic inside `onBackCompleted` maintains a strict 1:1 mapping between
256
+ `NavigationEventState` and the handler, preventing state collisions.
257
+
258
+
259
+ ```kotlin
260
+ // RIGHT
261
+ val navigationState = rememberNavigationEventState(currentInfo = NavigationEventInfo.None)
262
+ NavigationBackHandler(
263
+ state = navigationState,
264
+ isBackEnabled = true,
265
+ onBackCompleted = {
266
+ if (hasUnsavedChanges) {
267
+ showDiscardDialog()
268
+ } else {
269
+ onNavigateUp()
270
+ }
271
+ }
272
+ )
273
+ ```
274
+
275
+ <br />
276
+
277
+ #### WRONG
278
+
279
+ **Why this is WRONG** : Attaching multiple `NavigationBackHandler` composables to
280
+ the same `navigationState` instance attempts to bind duplicate handlers to a
281
+ single state object, which throws an `IllegalArgumentException` at runtime.
282
+
283
+
284
+ ```kotlin
285
+ // WRONG
286
+ val navigationState = rememberNavigationEventState(currentInfo = NavigationEventInfo.None)
287
+ NavigationBackHandler(
288
+ state = navigationState,
289
+ isBackEnabled = hasUnsavedChanges,
290
+ onBackCompleted = { /* Discard changes */ }
291
+ )
292
+ NavigationBackHandler(
293
+ state = navigationState,
294
+ isBackEnabled = !hasUnsavedChanges,
295
+ onBackCompleted = { /* Navigate up */ }
296
+ )
297
+ ```
298
+
299
+ <br />
300
+
301
+ ## Checklist
302
+
303
+ **For Compose Android targets:**
304
+
305
+ - \[ \] Is compile SDK set to `36` or higher? (If compile SDK is lower than 36, set it to `36` or higher in `build.gradle.kts`).
306
+ - \[ \] Is `android:enableOnBackInvokedCallback` NOT explicitly set to `"false"` in `AndroidManifest.xml`? (On API 36+, it defaults to `"true"`; on API 33--35, ensure it is set to `"true"`).
307
+ - \[ \] Does the Activity rely on the built-in `ComponentActivity` dispatcher owner without redundant anonymous delegate wrapping?
308
+ - \[ \] Do dialogs or sheets rely on automatic `ComponentDialog` dispatcher resolution without redundant `CompositionLocalProvider` wrapping?
309
+ - \[ \] Are parent-child dispatcher relationships in Compose scoped using `rememberNavigationEventDispatcherOwner()` when managing nested hierarchies?
310
+ - \[ \] Is conditional back logic handled within a single unified `NavigationBackHandler` to avoid duplicate registration (`IllegalArgumentException`)?
311
+ - \[ \] Are legacy `BackHandler` usages migrated to `NavigationBackHandler` with predictive progress support?
312
+ - \[ \] Does the project build and pass tests successfully?