2024-12-23 11:43:04 +01:00
|
|
|
import type * as React from 'react'
|
2024-12-01 10:07:35 +01:00
|
|
|
import { useInView } from 'react-intersection-observer'
|
|
|
|
|
|
2024-07-11 21:43:38 +02:00
|
|
|
import { useRouter } from '../hooks/useRouter'
|
2024-08-14 20:50:47 +02:00
|
|
|
import useRoute from '../hooks/useRoute'
|
|
|
|
|
|
2024-12-23 11:43:04 +01:00
|
|
|
interface TuonoLinkProps extends React.AnchorHTMLAttributes<HTMLAnchorElement> {
|
2024-11-04 19:29:37 +01:00
|
|
|
/**
|
2024-12-23 11:43:04 +01:00
|
|
|
* If "true" the route gets loaded when the link enters the viewport.
|
|
|
|
|
* @default true
|
2024-11-04 19:29:37 +01:00
|
|
|
*/
|
2024-08-14 20:50:47 +02:00
|
|
|
preload?: boolean
|
2024-12-23 11:43:04 +01:00
|
|
|
|
2024-11-04 19:29:37 +01:00
|
|
|
/**
|
2024-12-23 11:43:04 +01:00
|
|
|
* If "false" the scroll offset will be kept across page navigation.
|
|
|
|
|
* @default true
|
2024-11-04 19:29:37 +01:00
|
|
|
*/
|
|
|
|
|
scroll?: boolean
|
2024-08-14 20:50:47 +02:00
|
|
|
}
|
2024-05-11 15:08:49 +02:00
|
|
|
|
|
|
|
|
export default function Link(
|
2024-12-23 11:43:04 +01:00
|
|
|
componentProps: TuonoLinkProps,
|
2024-11-13 08:33:48 +01:00
|
|
|
): React.JSX.Element {
|
2024-12-23 11:43:04 +01:00
|
|
|
const {
|
|
|
|
|
preload = true,
|
|
|
|
|
scroll = true,
|
|
|
|
|
children,
|
|
|
|
|
href,
|
|
|
|
|
onClick,
|
|
|
|
|
...rest
|
|
|
|
|
} = componentProps
|
|
|
|
|
|
2024-07-11 21:43:38 +02:00
|
|
|
const router = useRouter()
|
2024-12-23 11:43:04 +01:00
|
|
|
const route = useRoute(href)
|
2024-08-14 20:50:47 +02:00
|
|
|
const { ref } = useInView({
|
|
|
|
|
onChange(inView) {
|
|
|
|
|
if (inView && preload) route?.component.preload()
|
|
|
|
|
},
|
|
|
|
|
triggerOnce: true,
|
|
|
|
|
})
|
2024-07-11 21:43:38 +02:00
|
|
|
|
2024-12-23 11:43:04 +01:00
|
|
|
const handleTransition: React.MouseEventHandler<HTMLAnchorElement> = (
|
|
|
|
|
event,
|
|
|
|
|
) => {
|
|
|
|
|
event.preventDefault()
|
|
|
|
|
onClick?.(event)
|
2024-08-16 11:21:18 +02:00
|
|
|
|
2024-12-23 11:43:04 +01:00
|
|
|
if (href?.startsWith('#')) {
|
|
|
|
|
window.location.hash = href
|
2024-08-16 11:21:18 +02:00
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
2024-12-23 11:43:04 +01:00
|
|
|
router.push(href || '', { scroll })
|
2024-05-11 15:08:49 +02:00
|
|
|
}
|
2024-07-11 21:43:38 +02:00
|
|
|
|
2024-05-11 15:08:49 +02:00
|
|
|
return (
|
2024-12-23 11:43:04 +01:00
|
|
|
<a {...rest} href={href} ref={ref} onClick={handleTransition}>
|
|
|
|
|
{children}
|
2024-05-11 15:08:49 +02:00
|
|
|
</a>
|
|
|
|
|
)
|
|
|
|
|
}
|