Implement main app navigation
This commit is contained in:
@@ -0,0 +1,91 @@
|
||||
---
|
||||
phase: 02.1
|
||||
plan: 04
|
||||
subsystem: navigation
|
||||
tags: [kotlin, compose-multiplatform, navigation, navigation-compose, type-safe-routes, multi-back-stack]
|
||||
requires: ["02.1-01", "02.1-02"]
|
||||
provides:
|
||||
- "navigation/Routes.kt — 8 @Serializable route types (4 graphs + 4 home destinations)"
|
||||
- "navigation/BottomBarDestination.kt — enum binding routes ↔ string resources ↔ icons ↔ search visibility"
|
||||
- "navigation/RootNavHost.kt — single root NavHost with 4 nested navigation() sub-graphs"
|
||||
- "navigation/NavExtensions.kt — NavHostController.navigateToTab() with four-flag multi-back-stack incantation"
|
||||
- "9 new shared shell/search keys in strings.xml"
|
||||
affects:
|
||||
- "composeApp/src/commonMain/composeResources/values/strings.xml (append-only — 9 new keys)"
|
||||
- "composeApp/src/commonTest/kotlin/dev/ulfrx/recipe/navigation/NavigationTest.kt (un-Ignored, real assertions)"
|
||||
tech-stack:
|
||||
added:
|
||||
- "androidx.navigation.compose.NavHost / navigation / composable (typed routes via @Serializable)"
|
||||
- "androidx.navigation.navOptions DSL (used in tests)"
|
||||
patterns:
|
||||
- "Multi-back-stack tab navigation: popUpTo(graph.findStartDestination().id){saveState=true} + launchSingleTop + restoreState"
|
||||
- "Per-tab parent NavBackStackEntry retrieval for future Koin VM scoping (RESEARCH § Pattern 2)"
|
||||
key-files:
|
||||
created:
|
||||
- "composeApp/src/commonMain/kotlin/dev/ulfrx/recipe/navigation/Routes.kt"
|
||||
- "composeApp/src/commonMain/kotlin/dev/ulfrx/recipe/navigation/BottomBarDestination.kt"
|
||||
- "composeApp/src/commonMain/kotlin/dev/ulfrx/recipe/navigation/RootNavHost.kt"
|
||||
- "composeApp/src/commonMain/kotlin/dev/ulfrx/recipe/navigation/NavExtensions.kt"
|
||||
modified:
|
||||
- "composeApp/src/commonMain/composeResources/values/strings.xml"
|
||||
- "composeApp/src/commonTest/kotlin/dev/ulfrx/recipe/navigation/NavigationTest.kt"
|
||||
decisions:
|
||||
- "Used Icons.AutoMirrored.Outlined.MenuBook (deprecation warning was fatal under -Werror)"
|
||||
- "TabHomePlaceholder uses BasicText from compose-foundation — avoids Material 1/3"
|
||||
- "NavigationTest uses navOptions{} DSL with public shouldXxx() accessors; fake-builder fallback was not needed"
|
||||
metrics:
|
||||
duration: ~6m
|
||||
completed: 2026-05-08
|
||||
---
|
||||
|
||||
# Phase 02.1 Plan 04: Navigation Foundation Summary
|
||||
|
||||
Type-safe navigation skeleton with 4 nested tab graphs (Planner/Recipes/Pantry/Shopping), a `BottomBarDestination` enum exposing routes/labels/icons/search visibility, and a `navigateToTab` extension that enforces the multi-back-stack four-flag contract — verified by 3 unit tests.
|
||||
|
||||
## What Was Built
|
||||
|
||||
- **Routes.kt** — 8 `@Serializable data object` types: PlannerGraph/PlannerHome, RecipesGraph/RecipesHome, PantryGraph/PantryHome, ShoppingGraph/ShoppingHome.
|
||||
- **BottomBarDestination.kt** — enum in D-03 order (Planner first as `Default`); only Recipes + Pantry have `hasSearch=true`/non-null `searchPlaceholder`. Bound to `Icons.Outlined.{CalendarMonth,Inventory2,ShoppingCart}` and `Icons.AutoMirrored.Outlined.MenuBook`.
|
||||
- **RootNavHost.kt** — single root `NavHost(startDestination = PlannerGraph)` containing four `navigation<*Graph>(startDestination = *Home)` blocks. Each `composable<*Home>` retrieves the parent graph's `NavBackStackEntry` via `navController.getBackStackEntry(*Graph)` (Pattern 2 wired and ready for plan 02.1-08 to consume with `koinViewModel(viewModelStoreOwner = parent)`). Renders private `TabHomePlaceholder` using `BasicText` — no Material dependency.
|
||||
- **NavExtensions.kt** — `fun NavHostController.navigateToTab(graphRoute: Any)` applies `popUpTo(graph.findStartDestination().id){saveState=true}`, `launchSingleTop = true`, `restoreState = true`.
|
||||
- **strings.xml** — 9 new keys appended (4 tab labels + 2 search placeholders + 3 search a11y), Polish copy verbatim from UI-SPEC. All 7 existing `auth_*` keys preserved.
|
||||
- **NavigationTest.kt** — `@Ignore` removed; 3 tests assert the four-flag contract via the public `navOptions { ... }` DSL and `shouldLaunchSingleTop()` / `shouldRestoreState()` / `shouldPopUpToSaveState()` accessors.
|
||||
|
||||
## Verification
|
||||
|
||||
- `./gradlew :composeApp:compileKotlinIosSimulatorArm64 -q` → exit 0
|
||||
- `./gradlew :composeApp:iosSimulatorArm64Test --tests "dev.ulfrx.recipe.navigation.NavigationTest"` → BUILD SUCCESSFUL (3 tests pass)
|
||||
- `./gradlew :composeApp:linkDebugFrameworkIosSimulatorArm64 -q` → exit 0
|
||||
- All acceptance grep counts match per task.
|
||||
|
||||
## Deviations from Plan
|
||||
|
||||
### Auto-fixed Issues
|
||||
|
||||
**1. [Rule 1 - Bug] Deprecated `Icons.Outlined.MenuBook` failed -Werror compile**
|
||||
- **Found during:** Task 1 verify
|
||||
- **Issue:** `'val Icons.Outlined.MenuBook: ImageVector' is deprecated. Use the AutoMirrored version` — Werror promoted the warning to a build failure.
|
||||
- **Fix:** Switched to `Icons.AutoMirrored.Outlined.MenuBook` and updated import.
|
||||
- **Files modified:** `composeApp/src/commonMain/kotlin/dev/ulfrx/recipe/navigation/BottomBarDestination.kt`
|
||||
- **Commit:** 9b9029a (folded into Task 1 commit)
|
||||
|
||||
No other deviations. Plan executed as written.
|
||||
|
||||
## Open Questions Resolved
|
||||
|
||||
- **navOptions DSL availability under nav-compose 2.9.2 K/N:** Public `navOptions { ... }` builder and `shouldLaunchSingleTop()` / `shouldRestoreState()` / `shouldPopUpToSaveState()` accessors are all publicly exposed. The fake-builder fallback path described in the plan was not needed.
|
||||
- **TabHomePlaceholder text strategy:** Settled on `androidx.compose.foundation.text.BasicText` — keeps the placeholder Material-free per UI-SPEC line 31. Plan 02.1-08 will replace with real `Tab*Screen` composables.
|
||||
|
||||
## Commits
|
||||
|
||||
- 9b9029a `feat(02.1-04): add type-safe routes and bottom bar destinations`
|
||||
- 5634171 `feat(02.1-04): add RootNavHost and navigateToTab extension`
|
||||
- 41d9bf4 `test(02.1-04): assert navigateToTab applies four-flag back-stack contract`
|
||||
|
||||
## Self-Check: PASSED
|
||||
|
||||
- FOUND: composeApp/src/commonMain/kotlin/dev/ulfrx/recipe/navigation/Routes.kt
|
||||
- FOUND: composeApp/src/commonMain/kotlin/dev/ulfrx/recipe/navigation/BottomBarDestination.kt
|
||||
- FOUND: composeApp/src/commonMain/kotlin/dev/ulfrx/recipe/navigation/RootNavHost.kt
|
||||
- FOUND: composeApp/src/commonMain/kotlin/dev/ulfrx/recipe/navigation/NavExtensions.kt
|
||||
- FOUND commit 9b9029a, 5634171, 41d9bf4
|
||||
Reference in New Issue
Block a user