|
| 1 | +import { useCallback } from 'react'; |
| 2 | +import type { RouteModel } from '@ember/routing/router-service'; |
| 3 | +import type Transition from '@ember/routing/transition'; |
| 4 | +import { useEmberService } from '../../hooks'; |
| 5 | +import { parseUrl } from '../../utils/url'; |
| 6 | +import type { UrlObject } from '../../types/router'; |
| 7 | + |
| 8 | +interface PolymorphicNavigate { |
| 9 | + ( |
| 10 | + to: string | Path, |
| 11 | + options?: NavigateOptions, |
| 12 | + ): void | Promise<void> | Promise<boolean>; |
| 13 | +} |
| 14 | + |
| 15 | +interface Path |
| 16 | + extends Partial<{ |
| 17 | + hash: string; |
| 18 | + pathname: string; |
| 19 | + search: string; |
| 20 | + }> { |
| 21 | + pathname: string; |
| 22 | +} |
| 23 | + |
| 24 | +type RelativeRoutingType = 'route' | 'path'; |
| 25 | + |
| 26 | +interface NavigateOptions { |
| 27 | + flushSync?: boolean; |
| 28 | + preventScrollReset?: boolean; |
| 29 | + relative?: RelativeRoutingType; |
| 30 | + replace?: boolean; |
| 31 | + // eslint-disable-next-line @typescript-eslint/no-explicit-any -- this comes from react router |
| 32 | + state?: any; |
| 33 | + viewTransition?: boolean; |
| 34 | +} |
| 35 | + |
| 36 | +export const useNavigate = (): PolymorphicNavigate => { |
| 37 | + const emberRouter = useEmberService('router'); |
| 38 | + |
| 39 | + return useCallback( |
| 40 | + ( |
| 41 | + url: string | UrlObject, |
| 42 | + options: NavigateOptions = {}, |
| 43 | + ): Promise<boolean> => { |
| 44 | + const parsedUrl = parseUrl(url); |
| 45 | + const { queryParams, params } = emberRouter.recognize(parsedUrl); |
| 46 | + const models = Object.values(params) as RouteModel[]; |
| 47 | + let transition: Transition<boolean>; |
| 48 | + if (options.replace) { |
| 49 | + transition = emberRouter.replaceWith(parsedUrl, models, { |
| 50 | + queryParams, |
| 51 | + }) as Transition<boolean>; |
| 52 | + } else { |
| 53 | + transition = emberRouter.transitionTo(parsedUrl, models, { |
| 54 | + queryParams, |
| 55 | + }) as Transition<boolean>; |
| 56 | + } |
| 57 | + return transition.promise; |
| 58 | + }, |
| 59 | + [emberRouter], |
| 60 | + ); |
| 61 | +}; |
0 commit comments