diff --git a/.changeset/link-focus-visible.md b/.changeset/link-focus-visible.md new file mode 100644 index 0000000000..4af0f661e4 --- /dev/null +++ b/.changeset/link-focus-visible.md @@ -0,0 +1,5 @@ +--- +'@backstage/ui': patch +--- + +Fix `Card href=...` not showing a focus indicator on keyboard navigation. `Link` now composes `useFocusRing` and emits `data-focus-visible`, so the Card's existing focus-ring CSS matches when the trigger is focused. diff --git a/packages/ui/src/components/Link/Link.tsx b/packages/ui/src/components/Link/Link.tsx index a66506deb0..47564ad24c 100644 --- a/packages/ui/src/components/Link/Link.tsx +++ b/packages/ui/src/components/Link/Link.tsx @@ -15,7 +15,7 @@ */ import { forwardRef, useRef } from 'react'; -import { useLink } from 'react-aria'; +import { mergeProps, useFocusRing, useLink } from 'react-aria'; import type { LinkProps } from './types'; import { useDefinition } from '../../hooks/useDefinition'; import { useResolvedHref } from '../../hooks/useResolvedHref'; @@ -33,6 +33,7 @@ const LinkInternal = forwardRef((props, ref) => { const linkRef = (ref || internalRef) as React.RefObject; const { linkProps } = useLink(restProps, linkRef); + const { isFocusVisible, focusProps } = useFocusRing(); const resolvedHref = useResolvedHref(restProps.href); const handleClick = (e: React.MouseEvent) => { @@ -48,13 +49,14 @@ const LinkInternal = forwardRef((props, ref) => { return ( )} href={resolvedHref} ref={linkRef} title={title} className={classes.root} + data-focus-visible={isFocusVisible || undefined} onClick={handleClick} > {children}