UNPKG

@layr/react-integration

Version:
70 lines 3.4 kB
import { normalizeURL } from '@layr/navigator'; import React, { useMemo, useCallback, useEffect } from 'react'; import { hasOwnProperty } from 'core-helpers'; export function BrowserNavigatorPlugin() { return function (navigator) { navigator.addAddressableMethodWrapper(function (receiver, method, params) { if (hasOwnProperty(method, '__isView')) { return React.createElement(method, params); } else { return method.call(receiver, params); } }); navigator.addCustomRouteDecorator(function (method) { method.Link = function ({ params, hash, ...props }) { const to = method.generateURL(params, { hash }); return navigator.Link({ to, ...props }); }; }); Object.assign(navigator, { Link(props) { const { to, className, activeClassName, style, activeStyle, ...otherProps } = props; if ('onClick' in props) { throw new Error(`The 'onClick' prop is not allowed in the 'Link' component`); } const handleClick = useCallback((event) => { if (!(event.shiftKey || event.ctrlKey || event.altKey || event.metaKey)) { event.preventDefault(); navigator.navigate(to, { defer: false }); } }, [to]); const currentPath = navigator.getCurrentPath(); const linkPath = normalizeURL(to).pathname; const isActive = linkPath === currentPath; const { actualClassName, actualStyle } = useMemo(() => { let actualClassName = className; let actualStyle = style; if (isActive) { if (activeClassName !== undefined) { const classes = actualClassName !== undefined ? [actualClassName] : []; classes.push(activeClassName); actualClassName = classes.join(' '); } if (activeStyle !== undefined) { actualStyle = { ...actualStyle, ...activeStyle }; } } return { actualClassName, actualStyle }; }, [isActive, className, activeClassName, style, activeStyle]); return (React.createElement("a", { href: to, onClick: handleClick, className: actualClassName, style: actualStyle, ...otherProps })); }, useBlocker(isBlocked) { useEffect(() => () => { // Always unblock the navigator when the associated React component unmounts navigator.unblock(); }, []); navigator.setIsBlocked(isBlocked); }, useBeforeNavigate(beforeNavigate) { useEffect(() => () => { // Always remove the navigator `beforeNavigate` hook when the associated // React component unmounts navigator.setBeforeNavigate(undefined); }, []); navigator.setBeforeNavigate(beforeNavigate); } }); }; } //# sourceMappingURL=plugins.js.map