import { useQueryClient } from '@tanstack/react-query' import { useMemo } from 'react' import { useNavigate } from 'react-router-dom' import { useOverlayStore } from '@/components/RouteBlockerOverlay' import { prefetchForURL } from '@/lib/prefetchers' import { cn } from '@/lib/utils' import type { AnchorHTMLAttributes, FC, MouseEvent, TouchEvent } from 'react' type Props = AnchorHTMLAttributes & { to: string replace?: boolean className?: string cancelOnError?: boolean } export default (({ to, replace, className, onMouseEnter, onTouchStart, onClick, cancelOnError = false, ...rest }: Props) => { const navigate = useNavigate () const qc = useQueryClient () const url = useMemo (() => (new URL (to, location.origin)).toString (), [to]) const setOverlay = useOverlayStore (s => s.setActive) const doPrefetch = async () => { try { await prefetchForURL (qc, url) return true } catch (e) { console.error ('データ取得エラー', e) return false } } const handleMouseEnter = async (ev: MouseEvent) => { onMouseEnter?.(ev) doPrefetch () } const handleTouchStart = async (ev: TouchEvent) => { onTouchStart?.(ev) doPrefetch () } const handleClick = async (ev: MouseEvent) => { onClick?.(ev) if (ev.defaultPrevented || ev.metaKey || ev.ctrlKey || ev.shiftKey || ev.altKey) return ev.preventDefault () setOverlay (true) const ok = await doPrefetch () setOverlay (false) if (!(ok) && cancelOnError) return navigate (to, { replace }) } return ( ) }) satisfies FC