refactor(packages/tuono-router): use named imports (#629)

This commit is contained in:
Marco Pasqualetti
2025-03-08 10:48:36 +01:00
committed by GitHub
parent 9db6f02701
commit fd2357cedc
7 changed files with 28 additions and 31 deletions
@@ -1,7 +1,7 @@
import { describe, it, expect, vi, beforeEach } from 'vitest' import { describe, it, expect, vi, beforeEach } from 'vitest'
import { render, fireEvent, screen } from '@testing-library/react' import { render, fireEvent, screen } from '@testing-library/react'
import Link from './Link' import { Link } from './Link'
const pushMock = vi.fn() const pushMock = vi.fn()
const replaceMock = vi.fn() const replaceMock = vi.fn()
@@ -1,4 +1,4 @@
import type * as React from 'react' import type { JSX, MouseEvent } from 'react'
import { useInView } from 'react-intersection-observer' import { useInView } from 'react-intersection-observer'
import { useRouter } from '../hooks/useRouter' import { useRouter } from '../hooks/useRouter'
@@ -25,7 +25,7 @@ interface TuonoLinkProps extends React.AnchorHTMLAttributes<HTMLAnchorElement> {
} }
function isEventModifierKeyActiveAndTargetDifferentFromSelf( function isEventModifierKeyActiveAndTargetDifferentFromSelf(
event: React.MouseEvent<HTMLAnchorElement>, event: MouseEvent<HTMLAnchorElement>,
): boolean { ): boolean {
const target = event.currentTarget.getAttribute('target') const target = event.currentTarget.getAttribute('target')
return ( return (
@@ -37,9 +37,7 @@ function isEventModifierKeyActiveAndTargetDifferentFromSelf(
) )
} }
export default function Link( export function Link(componentProps: TuonoLinkProps): JSX.Element {
componentProps: TuonoLinkProps,
): React.JSX.Element {
const { const {
preload = true, preload = true,
scroll = true, scroll = true,
@@ -1,9 +1,9 @@
import type * as React from 'react' import type { JSX } from 'react'
import { useRoute } from '../hooks/useRoute' import { useRoute } from '../hooks/useRoute'
import { RouteMatch } from './RouteMatch' import { RouteMatch } from './RouteMatch'
import NotFound from './NotFound' import { NotFound } from './NotFound'
import { useRouterContext } from './RouterContext' import { useRouterContext } from './RouterContext'
interface MatchesProps<TServerPayloadData = unknown> { interface MatchesProps<TServerPayloadData = unknown> {
@@ -11,9 +11,7 @@ interface MatchesProps<TServerPayloadData = unknown> {
serverInitialData: TServerPayloadData serverInitialData: TServerPayloadData
} }
export function Matches({ export function Matches({ serverInitialData }: MatchesProps): JSX.Element {
serverInitialData,
}: MatchesProps): React.JSX.Element {
const { location } = useRouterContext() const { location } = useRouterContext()
const route = useRoute(location.pathname) const route = useRoute(location.pathname)
@@ -1,11 +1,11 @@
import type * as React from 'react' import type { JSX } from 'react'
import { useRouterContext } from '../components/RouterContext' import { useRouterContext } from '../components/RouterContext'
import { RouteMatch } from './RouteMatch' import { RouteMatch } from './RouteMatch'
import Link from './Link' import { Link } from './Link'
export default function NotFound(): React.JSX.Element { export function NotFound(): JSX.Element {
const { router } = useRouterContext() const { router } = useRouterContext()
const custom404Route = router.routesById['/404'] const custom404Route = router.routesById['/404']
@@ -1,4 +1,5 @@
import * as React from 'react' import type { JSX } from 'react'
import { memo, Suspense, useMemo } from 'react'
import type { Route } from '../route' import type { Route } from '../route'
import { useServerPayloadData } from '../hooks/useServerPayloadData' import { useServerPayloadData } from '../hooks/useServerPayloadData'
@@ -16,18 +17,18 @@ interface RouteMatchProps<TServerPayloadData = unknown> {
*/ */
export const RouteMatch = ({ export const RouteMatch = ({
route, route,
serverInitialData: serverInitialData, serverInitialData,
}: RouteMatchProps): React.JSX.Element => { }: RouteMatchProps): JSX.Element => {
const { data, isLoading } = useServerPayloadData(route, serverInitialData) const { data, isLoading } = useServerPayloadData(route, serverInitialData)
// eslint-disable-next-line react-hooks/exhaustive-deps // eslint-disable-next-line react-hooks/exhaustive-deps
const routes = React.useMemo(() => loadParentComponents(route), [route.id]) const routes = useMemo(() => loadParentComponents(route), [route.id])
return ( return (
<TraverseRootComponents routes={routes} data={data} isLoading={isLoading}> <TraverseRootComponents routes={routes} data={data} isLoading={isLoading}>
<React.Suspense> <Suspense>
<route.component data={data} isLoading={isLoading} /> <route.component data={data} isLoading={isLoading} />
</React.Suspense> </Suspense>
</TraverseRootComponents> </TraverseRootComponents>
) )
} }
@@ -40,13 +41,13 @@ interface TraverseRootComponentsProps<TData = unknown> {
index?: number index?: number
} }
/* /**
* This component traverses and renders * This component traverses and renders all components
* all the components that wraps the selected route (__layout). * that wrap the selected route (__layout).
* The parents components need to be memoized in order to avoid * Parent components must be memoized
* re-rendering bugs when changing route. * to prevent re-rendering issues when the route changes.
*/ */
const TraverseRootComponents = React.memo( const TraverseRootComponents = memo(
({ ({
routes, routes,
data, data,
+4 -4
View File
@@ -1,4 +1,4 @@
import React from 'react' import { useCallback } from 'react'
import { useRouterContext } from '../components/RouterContext' import { useRouterContext } from '../components/RouterContext'
@@ -38,7 +38,7 @@ interface UseRouterResult {
export const useRouter = (): UseRouterResult => { export const useRouter = (): UseRouterResult => {
const { location, updateLocation } = useRouterContext() const { location, updateLocation } = useRouterContext()
const navigate = React.useCallback( const navigate = useCallback(
(type: NavigationType, path: string, opts?: NavigationOptions): void => { (type: NavigationType, path: string, opts?: NavigationOptions): void => {
const { scroll = true } = opts || {} const { scroll = true } = opts || {}
const url = new URL(path, window.location.origin) const url = new URL(path, window.location.origin)
@@ -60,14 +60,14 @@ export const useRouter = (): UseRouterResult => {
[updateLocation], [updateLocation],
) )
const push = React.useCallback( const push = useCallback(
(path: string, opts?: NavigationOptions): void => { (path: string, opts?: NavigationOptions): void => {
navigate('pushState', path, opts) navigate('pushState', path, opts)
}, },
[navigate], [navigate],
) )
const replace = React.useCallback( const replace = useCallback(
(path: string, opts?: NavigationOptions): void => { (path: string, opts?: NavigationOptions): void => {
navigate('replaceState', path, opts) navigate('replaceState', path, opts)
}, },
+1 -1
View File
@@ -1,5 +1,5 @@
export { RouterProvider } from './components/RouterProvider' export { RouterProvider } from './components/RouterProvider'
export { default as Link } from './components/Link' export { Link } from './components/Link'
export { createRouter } from './router' export { createRouter } from './router'
export type { RouterInstanceType } from './router' export type { RouterInstanceType } from './router'
export { createRoute, createRootRoute } from './route' export { createRoute, createRootRoute } from './route'