1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677 |
- import {forwardRef, useEffect} from 'react';
- // eslint-disable-next-line no-restricted-imports
- import {Link as RouterLink, withRouter, WithRouterProps} from 'react-router';
- import styled from '@emotion/styled';
- import * as Sentry from '@sentry/react';
- import {Location, LocationDescriptor} from 'history';
- import {linkStyles} from './styles';
- export interface LinkProps
- extends Omit<
- React.DetailedHTMLProps<React.HTMLAttributes<HTMLAnchorElement>, HTMLAnchorElement>,
- 'href' | 'target' | 'as' | 'css'
- > {
- /**
- * The string path or LocationDescriptor object
- */
- to: ((location: Location) => LocationDescriptor) | LocationDescriptor;
- /**
- * Style applied to the component's root
- */
- className?: string;
- /**
- * Indicator if the link should be disabled
- */
- disabled?: boolean;
- /**
- * Forwarded ref
- */
- forwardedRef?: React.Ref<HTMLAnchorElement>;
- }
- /**
- * A context-aware version of Link (from react-router) that falls
- * back to <a> if there is no router present
- */
- interface WithRouterBaseLinkProps extends WithRouterProps, LinkProps {}
- function BaseLink({
- location,
- disabled,
- to,
- forwardedRef,
- router: _router,
- params: _params,
- routes: _routes,
- ...props
- }: WithRouterBaseLinkProps): React.ReactElement {
- useEffect(() => {
- // check if the router is present
- if (!location) {
- Sentry.captureException(
- new Error('The link component was rendered without being wrapped by a <Router />')
- );
- }
- }, [location]);
- if (!disabled && location) {
- return <RouterLink to={to} ref={forwardedRef as any} {...props} />;
- }
- return <a href={typeof to === 'string' ? to : ''} ref={forwardedRef} {...props} />;
- }
- // Re-assign to Link to make auto-importing smarter
- const Link = withRouter(
- styled(
- forwardRef<HTMLAnchorElement, Omit<WithRouterBaseLinkProps, 'forwardedRef'>>(
- (props, ref) => <BaseLink forwardedRef={ref} {...props} />
- )
- )`
- ${linkStyles}
- `
- );
- export default Link;
|