UNPKG

@dnb/eufemia

Version:

DNB Eufemia Design System UI Library

88 lines (87 loc) 2.9 kB
"use client"; import { useCallback, useRef } from 'react'; import useStep from "./useStep.js"; import { useIsomorphicLayoutEffect as useLayoutEffect } from "../../../../shared/helpers/useIsomorphicLayoutEffect.js"; const routerStepChanges = new Map(); export default function useReachRouter(id = null, { useLocation, navigate }) { const name = id ? `${id}-step` : 'step'; const { setFormError } = useStep(id); const location = useLocation(); const locationRef = useRef(location); locationRef.current = location; const navigateRef = useRef(navigate); navigateRef.current = navigate; const routerStepChangeRef = useRef(undefined); const hasRouterStepRef = useRef(false); const onStepChange = useCallback(index => { try { const locationUrl = new URL(locationRef.current.href); const url = typeof window !== 'undefined' ? new URL(window.location.href) : locationUrl; if (parseFloat(url.searchParams.get(name)) === index || routerStepChangeRef.current === index || routerStepChanges.get(name) === index) { return; } routerStepChangeRef.current = index; routerStepChanges.set(name, index); hasRouterStepRef.current = true; url.searchParams.set(name, String(index)); navigateRef.current(url.href); } catch (error) { routerStepChanges.delete(name); setFormError(error); } }, [name, setFormError]); const { setActiveIndex, onStepChangeEventsRef } = useStep(id, { onStepChange }); useLayoutEffect(() => { return () => { if (routerStepChanges.get(name) === routerStepChangeRef.current) { routerStepChanges.delete(name); } }; }, [name]); useLayoutEffect(() => { return () => { onStepChangeEventsRef?.current?.delete(onStepChange); }; }, [onStepChange, onStepChangeEventsRef]); const getIndex = useCallback(() => { try { const searchParams = new URLSearchParams(location.search); return parseFloat(searchParams.get(name)); } catch (error) { setFormError(error); } return undefined; }, [location.search, name, setFormError]); useLayoutEffect(() => { const routerIndex = getIndex(); const hasRouterIndex = !isNaN(routerIndex); if (hasRouterIndex) { hasRouterStepRef.current = true; } if (hasRouterIndex || hasRouterStepRef.current) { const activeIndex = hasRouterIndex ? routerIndex : 0; const skipStepChangeCall = hasRouterIndex && activeIndex === routerStepChangeRef.current; routerStepChangeRef.current = undefined; routerStepChanges.delete(name); setActiveIndex?.(activeIndex, { skipStepChangeCall, skipStepChangeCallFromHook: true, skipStepChangeCallBeforeMounted: true }); } }, [getIndex, name, setActiveIndex]); return { getIndex }; } //# sourceMappingURL=useReachRouter.js.map