/** * External dependencies */ import { partial } from 'lodash'; import { createElement } from '@wordpress/element'; import { getHistory } from '@woocommerce/navigation'; import React from 'react'; interface LinkProps { /** Type of link. For wp-admin and wc-admin, the correct prefix is appended. */ type?: 'wc-admin' | 'wp-admin' | 'external'; /** The resource to link to. */ href: string; } // eslint-disable-next-line @typescript-eslint/no-explicit-any type LinkOnClickHandlerFunction = ( ...props: any ) => any; // we don't want to restrict this function at all type LinkOnclickHandler = ( onClick: LinkOnClickHandlerFunction | undefined, event: React.MouseEvent< Element > | undefined ) => void; /** * Use `Link` to create a link to another resource. It accepts a type to automatically * create wp-admin links, wc-admin links, and external links. */ export const Link = ( { href, children, type = 'wc-admin', ...props }: React.AnchorHTMLAttributes< HTMLAnchorElement > & LinkProps ): React.ReactElement => { // ( { children, href, type, ...props } ) => { // @todo Investigate further if we can use directly. // With React Router 5+, cannot be used outside of the main elements, // which seems to include components imported from @woocommerce/components. For now, we can use the history object directly. const wcAdminLinkHandler: LinkOnclickHandler = ( onClick, event ) => { // If cmd, ctrl, alt, or shift are used, use default behavior to allow opening in a new tab. if ( event?.ctrlKey || event?.metaKey || event?.altKey || event?.shiftKey ) { return; } event?.preventDefault(); // If there is an onclick event, execute it. const onClickResult = onClick && event ? onClick( event ) : true; // Mimic browser behavior and only continue if onClickResult is not explicitly false. if ( onClickResult === false ) { return; } if ( event?.target instanceof Element ) { const closestEventTarget = event.target .closest( 'a' ) ?.getAttribute( 'href' ); if ( closestEventTarget ) { getHistory().push( closestEventTarget ); } else { // eslint-disable-next-line no-console console.error( '@woocommerce/components/link is trying to push an undefined state into navigation stack' ); // This shouldn't happen as we wrap with below } } }; const passProps = { ...props, 'data-link-type': type, }; if ( type === 'wc-admin' ) { passProps.onClick = partial( wcAdminLinkHandler, passProps.onClick ); } return ( { children } ); }; export default Link;