import React, { forwardRef, useCallback } from 'react'; import { clsx } from 'clsx'; import type { PrimitiveAnchorProps } from '.'; /** * The Primitive `PrimitiveAnchor` component is customisable link element that can be * used in various parts of the Wise Design System internally. It supports * different states such as disabled and provides event handlers for common * interactions like click, focus, blur, mouse enter, mouse leave, and key down. * * @see {@link PrimitiveAnchor} for further information. * @see {@link https://storybook.wise.design/?path=/docs/primitive-anchor--docs|Storybook Wise Design} */ const PrimitiveAnchor = forwardRef( ( { children, className, href, id, disabled = false, testId, onClick, onFocus, onBlur, onMouseEnter, onMouseLeave, onKeyDown, ...props }, ref, ) => { const anchorClasses = clsx(className); const handleClick = useCallback( (event: React.MouseEvent) => { if (disabled) { event.preventDefault(); } else { onClick?.(event); } }, [disabled, onClick], ); const handleFocus = useCallback( (event: React.FocusEvent) => { onFocus?.(event); }, [onFocus], ); const handleBlur = useCallback( (event: React.FocusEvent) => { onBlur?.(event); }, [onBlur], ); const handleMouseEnter = useCallback( (event: React.MouseEvent) => { onMouseEnter?.(event); }, [onMouseEnter], ); const handleMouseLeave = useCallback( (event: React.MouseEvent) => { onMouseLeave?.(event); }, [onMouseLeave], ); const handleKeyDown = useCallback( (event: React.KeyboardEvent) => { onKeyDown?.(event); }, [onKeyDown], ); /** * The following props are set to handle the `disabled` state for the link: * * - `aria-disabled`: Exposes the link as disabled to assistive technologies. * - `href`: Removed when `disabled` is true to prevent navigation. * - `role`: Set to 'link' when `disabled` is true to ensure the element * is still exposed as a link. * * For more details, refer to Scott O'Hara's article on disabling links: * https://www.scottohara.me/blog/2021/05/28/disabled-links.html */ const anchorProps = { 'aria-disabled': disabled || undefined, className: anchorClasses, 'data-testid': testId, href: disabled ? undefined : href, id, ref, role: disabled ? 'link' : undefined, rel: props.target === '_blank' ? 'noopener noreferrer' : undefined, onClick: handleClick, onFocus: handleFocus, onBlur: handleBlur, onMouseEnter: handleMouseEnter, onMouseLeave: handleMouseLeave, onKeyDown: handleKeyDown, ...props, }; return {children}; }, ); PrimitiveAnchor.displayName = 'PrimitiveAnchor'; export default PrimitiveAnchor;