Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ node_modules/
coverage/
npm-debug.log*
yarn-error.log
.yalc

# ember-try
/.node_modules.ember-try/
Expand Down
42 changes: 39 additions & 3 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 3 additions & 2 deletions react-migration-toolkit/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@qonto/react-migration-toolkit",
"version": "3.0.0",
"version": "3.0.1",
"description": "A toolkit to help migrate Ember components to React",
"keywords": [
"ember-addon"
Expand Down Expand Up @@ -137,9 +137,10 @@
}
},
"peerDependencies": {
"ember-intl": "^7.0.0 && <7.0.8",
"ember-source": "^3.28.0 || ^4.0.0 || ^5.0.0",
"react-intl": "^6.6.8",
"ember-intl": "^7.0.0 && <7.0.8"
"react-router": "7.6.3"
},
"peerDependenciesMeta": {
"react-intl": {
Expand Down
1 change: 1 addition & 0 deletions react-migration-toolkit/src/react/hooks/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
export { useEmberService } from './use-ember-service';
export { useApplicationInstance } from './use-application-instance';
export { useNavigate } from './use-navigate';
export { useIsEmberRoute } from './use-is-ember-route';
export { useRouter } from './use-router';
41 changes: 41 additions & 0 deletions react-migration-toolkit/src/react/hooks/use-is-ember-route.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import { useLocation, useInRouterContext } from 'react-router';
import type { UrlObject } from '../types/router';
import { useEmberService } from './use-ember-service';
import { useCallback } from 'react';
/**
* Determines whether the current route is handled by the Ember router.
*
* This hook inspects the application's router to check if the current path
* matches any Ember route handler, excluding those that contain "react" in their name.
* We need to apply a regex to explicitly exclude 'react' routes because,
* if not, 'react-fallback' and similar named routes would match would match.
*
* @returns true if the current route is an Ember route (not a React route), otherwise false.
*
* @remarks
* This is useful for hybrid applications where both Ember and React routes may coexist,
* and you need to conditionally render or handle logic based on the routing system in use.
*/
export const useIsEmberRoute = (): ((
pathname?: string | UrlObject,
) => boolean) => {
// avoids Uncaught Error: useLocation() may be used only in the context of a <Router> component
if (!useInRouterContext()) {
return () => true;
}
const location = useLocation();
const emberRouter = useEmberService('router');

return useCallback(
(path?: string | UrlObject) => {
// if inspection isn't possible, we assume Ember for backward compatibility
if (!emberRouter?.recognize) return true;

const targetPath =
typeof path === 'string' ? path : path?.pathname || location.pathname;
const routeName = emberRouter.recognize(targetPath).name;
return Boolean(routeName) && !/react/.exec(routeName);
},
[emberRouter, location.pathname],
);
};
31 changes: 27 additions & 4 deletions react-migration-toolkit/src/react/hooks/use-navigate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,36 @@ import {
PolymorphicNavigateContext,
type PolymorphicNavigate,
} from '../contexts/polymorphic-navigate-context';
import type { NavigateOptions } from 'react-router';
import {
useInRouterContext,
useNavigate as useReactRouterNavigate,
} from 'react-router';
import { useIsEmberRoute } from './use-is-ember-route';
import type { UrlObject } from '../types/router';

export const useNavigate = (): PolymorphicNavigate => {
const navigate = useContext(PolymorphicNavigateContext);
if (!navigate) {
const contextNavigate = useContext(PolymorphicNavigateContext);
if (!contextNavigate) {
throw new Error(
'this hook can only be used with PolymorphicNavigateProvider',
'useNavigate hook can only be used with PolymorphicNavigateProvider',
);
}
return navigate;

// avoids Uncaught Error: useNavigate() may be used only in the context of a <Router> component
if (!useInRouterContext()) {
return (to: string | UrlObject, options?: NavigateOptions) => {
return contextNavigate(to, options);
};
}

const isEmberRoute = useIsEmberRoute();
const reactRouterNavigate = useReactRouterNavigate();

return (to: string | UrlObject, options?: NavigateOptions) => {
if (isEmberRoute(to)) {
return contextNavigate(to, options);
}
return reactRouterNavigate(to, options);
};
};
1 change: 1 addition & 0 deletions react-migration-toolkit/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
"jsx": "react-jsx",
"allowJs": true,
"declarationDir": "declarations",
"lib": ["dom", "dom.iterable", "esnext"],
/**
https://www.typescriptlang.org/tsconfig#noEmit

Expand Down