diff --git a/docs/react-router/react-router-6-status.md b/docs/react-router/react-router-6-status.md deleted file mode 100644 index 5488c79967..0000000000 --- a/docs/react-router/react-router-6-status.md +++ /dev/null @@ -1,252 +0,0 @@ -# React Router 6 Migration - -**Branch:** `sk/react-router-6` -**Design Docs:** [PR #305](https://github.com/ionic-team/ionic-framework-design-documents/pull/305) -**Last Updated:** December 2, 2025 - -## Overview - -The `@ionic/react-router` package has been updated to support React Router 6. This migration replaces the React Router 5 integration with native RR6 APIs while preserving Ionic's navigation patterns, animations, and view lifecycle management. - -All Cypress tests are passing. - -| Metric | Count | -|--------|-------| -| Total tests | 77 | -| Passing | 77 | -| Failing | 0 | - -## What Changed - -### Package Dependencies - -The `@ionic/react-router` package now requires React Router 6: - -```json -"peerDependencies": { - "react-router": ">=6.0.0", - "react-router-dom": ">=6.0.0" -} -``` - -The `history` package dependency was updated from v4 to v5 (which RR6 uses internally). - -### Core Components - -**IonRouter** (`IonRouter.tsx`) was rewritten as a functional component using React hooks. It now uses `useLocation` and `useNavigate` from React Router 6 instead of the `withRouter` HOC and `history` object from v5. The component continues to manage `LocationHistory` and compute `RouteInfo` objects for Ionic's view stacks and transition directions. - -**ReactRouterViewStack** (`ReactRouterViewStack.tsx`) was substantially expanded to handle RR6's matching semantics. Key changes include: -- Support for RR6's `PathMatch` objects and pattern matching -- Handling of index routes and wildcard routes (`*`) -- View identity tracking for parameterized routes (`/user/:id`) -- Proper computation of parent paths for nested outlets -- View cleanup for cross-navigation scenarios (e.g., navigating between different tab stacks) - -**StackManager** (`StackManager.tsx`) was updated to work with the new view stack implementation. Changes include: -- Parent path derivation using RR6's route matching -- Improved handling of `Navigate` redirect components -- Better coordination of entering/leaving views during transitions -- Hiding of deactivated catch-all routes to prevent visual glitches - -**IonRouteInner** (`IonRouteInner.tsx`) was simplified to work with RR6's element-based routing instead of the component/render prop pattern. - -**Router Components** (`IonReactRouter.tsx`, `IonReactHashRouter.tsx`, `IonReactMemoryRouter.tsx`) were updated to use RR6's router components and hooks. - -### New Utilities - -Five utility modules were added to support RR6's routing model: - -| File | Purpose | -|------|---------| -| `computeParentPath.ts` | Computes common path prefixes and determines specific route matches for nested outlets | -| `pathMatching.ts` | Extended path matching using RR6's `matchPath` with support for index routes | -| `pathNormalization.ts` | Path string normalization (leading/trailing slashes) | -| `routeElements.ts` | Extracts Route children from Routes wrappers, detects Navigate elements | -| `viewItemUtils.ts` | Sorts views by route specificity for proper matching priority | - -The old `matchPath.ts` utility was removed as its functionality is now handled by RR6's native matching. - -### @ionic/react Changes - -Several changes were made to the `@ionic/react` package to support the migration: - -- **IonRoute** (`IonRoute.tsx`): Updated to work with RR6's element-based routing -- **IonRouterOutlet** (`IonRouterOutlet.tsx`): Updated for RR6 compatibility -- **LocationHistory** (`LocationHistory.ts`): Enhanced to track navigation direction more accurately -- **RouteManagerContext** (`RouteManagerContext.ts`): Added `clearOutletViews` method for cross-navigation cleanup -- **ViewLifeCycleManager** (`ViewLifeCycleManager.tsx`): Added support for new lifecycle events -- **createInlineOverlayComponent** (`createInlineOverlayComponent.tsx`): New utility to automatically dismiss inline overlays on navigation - -### Test App Updates - -All test pages in `packages/react-router/test/base/src/pages/` were updated to use RR6 syntax: -- `` became `} />` -- Nested routes now require trailing wildcards (`path="parent/*"`) when they contain child outlets -- `` became `` -- Route params accessed via `useParams()` instead of `props.match.params` -- Links use relative paths where appropriate - -A new test page (`nested-params/NestedParams.tsx`) was added to test parameterized nested routing scenarios. - -The `reactrouter5` test app was removed since the package no longer supports RR5. - -## Test Coverage - -The Cypress test suite covers the following scenarios: - -| Suite | Tests | Description | -|-------|-------|-------------| -| routing.cy.js | 29 | Core navigation, tabs, back button, redirects, params | -| nested-outlets.cy.js | 11 | Nested `IonRouterOutlet` behavior, back navigation | -| swipe-to-go-back.cy.js | 8 | Gesture navigation, abort handling, tab interactions | -| cross-route-navigation.cy.js | 7 | Navigation between different route contexts (tabs, outlets) | -| multiple-tabs.cy.js | 4 | Switching between different tab configurations | -| overlays.cy.js | 3 | Modal cleanup on navigation | -| dynamic-routes.cy.js | 3 | Adding routes at runtime | -| dynamic-tabs.cy.js | 3 | Adding tabs at runtime | -| tabs.cy.js | 2 | Basic tab navigation and history | -| tab-context.cy.js | 2 | Programmatic tab switching via context | -| refs.cy.js | 2 | Ref forwarding to Ionic components | -| dynamic-ionpage-classnames.cy.js | 1 | Dynamic class application to IonPage | -| outlet-ref.cy.js | 1 | Ref access to IonRouterOutlet | -| replace-actions.cy.js | 1 | History replacement behavior | - -### New Test Suite: Cross-Route Navigation - -A new test suite (`cross-route-navigation.cy.js`) was added to verify proper view cleanup when navigating between different route contexts: -- Tab-to-non-tab navigation -- Non-tab-to-tab navigation -- Between different tab configurations -- Deep link scenarios - -## Known Limitations - -### Route Path Syntax - -Nested outlets require parent routes to include a trailing wildcard: - -```tsx -// Correct -} /> - -// Incorrect - child routes won't match -} /> -``` - -This aligns with React Router 6's nested routing semantics where child routes are matched relative to the parent's path. - -### Relative vs Absolute Paths - -React Router 6 strongly favors relative paths for nested routing. While absolute paths still work, using relative paths in nested outlets is recommended: - -```tsx -// Inside a component at /tabs/home -Details // Navigates to /tabs/home/details -Details // Also works, but less flexible -``` - -## CI Integration - -The GitHub Actions workflows have been updated to run the RR6 test app: -- `.github/workflows/build.yml` -- `.github/workflows/stencil-nightly.yml` - -The matrix now uses `reactrouter6` instead of `reactrouter5`. - -## Architecture Reference - -The data flow through the routing system: - -``` -Browser History Change - | - v - IonRouter (useLocation/useNavigate) - | - +-- Updates LocationHistory - +-- Computes RouteInfo (action, direction, params) - | - v - RouteManagerContext - | - v - StackManager (per IonRouterOutlet) - | - +-- Derives parent path from route children - +-- Matches routes using ReactRouterViewStack - +-- Determines entering/leaving views - +-- Clears stale views on cross-navigation - | - v - ion-router-outlet.commit() - | - v - Native Ionic Transition -``` - -The key insight is that Ionic intercepts React Router's navigation events and translates them into its own view management system, which enables native-feeling animations and gestures while still using React Router for URL management. - -## Next Steps - -### Before Release - -1. ~~**Run a TypeScript strict check** on the `@ionic/react-router` package~~ Complete -2. ~~**All Cypress tests passing**~~ Complete (77/77) -3. **Manual testing pass** through the test app to verify animations and gestures feel correct -4. **Code review** of the implementation - -### Documentation - -The following documentation should be prepared before public release: - -1. **Migration guide** covering: - - Route syntax changes (`component` to `element`, `Redirect` to `Navigate`) - - Nested route wildcard requirements - - Accessing route params with hooks (`useParams()`) - - Link syntax changes (relative paths) - - Any removed or deprecated APIs - -2. **Updated API reference** for: - - `IonReactRouter`, `IonReactHashRouter`, `IonReactMemoryRouter` - - `IonRouterOutlet` behavior with nested routes - - `routeOptions.unmount` and `LocationHistory` behavior - -## Related Files - -Source code: -- `packages/react-router/src/ReactRouter/IonRouter.tsx` -- `packages/react-router/src/ReactRouter/ReactRouterViewStack.tsx` -- `packages/react-router/src/ReactRouter/StackManager.tsx` -- `packages/react-router/src/ReactRouter/IonRouteInner.tsx` -- `packages/react-router/src/ReactRouter/IonReactRouter.tsx` -- `packages/react-router/src/ReactRouter/IonReactHashRouter.tsx` -- `packages/react-router/src/ReactRouter/IonReactMemoryRouter.tsx` -- `packages/react-router/src/ReactRouter/utils/` (5 utility modules) - -Test infrastructure: -- `packages/react-router/test/base/` (shared test code) -- `packages/react-router/test/apps/reactrouter6/` (RR6 config) -- `packages/react-router/scripts/test_runner.sh` (test automation) - -Supporting changes in @ionic/react: -- `packages/react/src/components/IonRoute.tsx` -- `packages/react/src/components/IonRouterOutlet.tsx` -- `packages/react/src/components/createInlineOverlayComponent.tsx` -- `packages/react/src/routing/LocationHistory.ts` -- `packages/react/src/routing/RouteManagerContext.ts` -- `packages/react/src/routing/ViewLifeCycleManager.tsx` - -## Commit History - -Key commits on this branch: - -| Commit | Description | -|--------|-------------| -| `418ac75` | Cleaning up util files | -| `82fd1ba` | Fix views not being cleaned up properly, causing cross navigation issues | -| `3912623` | Hide deactivated catch-all routes | -| `7fd0659` | Nested redirect fix | -| `b02c197` | Prevent incorrect view reuse for parameterized routes | -| `584dcf2` | Prioritize specific route matches | -| `045b0a7` | Correct tab and nested outlet navigation | -| `59f2dbe` | Automatically dismiss inline overlays on navigation |