Link
A link allows a user to navigate to another page or resource within a web page or application.
install | yarn add react-aria-components |
---|---|
version | 3.17.0 |
usage | import {Link} from 'react-aria-components' |
Example#
import {Link} from 'react-aria-components';
<Link>
<a href="https://www.imdb.com/title/tt6348138/" target="_blank">
The missing link
</a>
</Link>
import {Link} from 'react-aria-components';
<Link>
<a
href="https://www.imdb.com/title/tt6348138/"
target="_blank"
>
The missing link
</a>
</Link>
import {Link} from 'react-aria-components';
<Link>
<a
href="https://www.imdb.com/title/tt6348138/"
target="_blank"
>
The missing link
</a>
</Link>
Show CSS
.react-aria-Link {
color: var(--spectrum-global-color-blue-600);
font-size: 18px;
transition: all 200ms;
text-decoration: underline;
cursor: pointer;
outline: none;
position: relative;
&[data-hovered] {
text-decoration-style: wavy;
}
&[data-pressed] {
color: var(--spectrum-global-color-blue-700);
}
&[aria-disabled] {
cursor: default;
color: gray;
}
&[data-focus-visible]:after {
content: '';
position: absolute;
inset: -1px -4px;
border-radius: 4px;
box-shadow: 0 0 0 2px slateblue;
}
}
.react-aria-Link {
color: var(--spectrum-global-color-blue-600);
font-size: 18px;
transition: all 200ms;
text-decoration: underline;
cursor: pointer;
outline: none;
position: relative;
&[data-hovered] {
text-decoration-style: wavy;
}
&[data-pressed] {
color: var(--spectrum-global-color-blue-700);
}
&[aria-disabled] {
cursor: default;
color: gray;
}
&[data-focus-visible]:after {
content: '';
position: absolute;
inset: -1px -4px;
border-radius: 4px;
box-shadow: 0 0 0 2px slateblue;
}
}
.react-aria-Link {
color: var(--spectrum-global-color-blue-600);
font-size: 18px;
transition: all 200ms;
text-decoration: underline;
cursor: pointer;
outline: none;
position: relative;
&[data-hovered] {
text-decoration-style: wavy;
}
&[data-pressed] {
color: var(--spectrum-global-color-blue-700);
}
&[aria-disabled] {
cursor: default;
color: gray;
}
&[data-focus-visible]:after {
content: '';
position: absolute;
inset: -1px -4px;
border-radius: 4px;
box-shadow: 0 0 0 2px slateblue;
}
}
Features#
Links can be created in HTML with the <a>
element with an href
attribute. However, if the link does not have an href, and is
handled client side with JavaScript instead, it will not be exposed to assistive technology properly.
Link
helps achieve accessible links with either native HTML elements or custom element types.
- Flexible – Support for navigation links, JavaScript handled links, or custom element types (e.g. router links). Disabled links are also supported.
- Accessible – Implemented as a custom ARIA link when handled via JavaScript, and otherwise as a native HTML link.
- Styleable – Hover, press, and keyboard focus states are provided for easy styling. These states only apply when interacting with an appropriate input device, unlike CSS pseudo classes.
Anatomy#
A link consists of a pressable area usually containing a textual label or an icon that users can click or tap to navigate to another page or resource. In addition, keyboard users may activate links using the Enter key.
If a visual label is not provided (e.g. an icon or image only link), then an aria-label
or
aria-labelledby
prop must be passed to identify the link to assistive technology.
Props#
Name | Type | Default | Description |
isDisabled | boolean | — | Whether the link is disabled. |
autoFocus | boolean | — | Whether the element should receive focus on render. |
children | ReactNode | (
(values: LinkRenderProps
)) => ReactNode | — | |
className | string | (
(values: LinkRenderProps
)) => string | — | |
style | CSSProperties | (
(values: LinkRenderProps
)) => CSSProperties | — |
Events
Name | Type | Default | Description |
onPress | (
(e: PressEvent
)) => void | — | Handler that is called when the press is released over the target. |
onPressStart | (
(e: PressEvent
)) => void | — | Handler that is called when a press interaction starts. |
onPressEnd | (
(e: PressEvent
)) => void | — | Handler that is called when a press interaction ends, either over the target or when the pointer leaves the target. |
onPressChange | (
(isPressed: boolean
)) => void | — | Handler that is called when the press state changes. |
onPressUp | (
(e: PressEvent
)) => void | — | Handler that is called when a press is released over the target, regardless of whether it started on the target or not. |
onFocus | (
(e: FocusEvent
)) => void | — | Handler that is called when the element receives focus. |
onBlur | (
(e: FocusEvent
)) => void | — | Handler that is called when the element loses focus. |
onFocusChange | (
(isFocused: boolean
)) => void | — | Handler that is called when the element's focus status changes. |
onKeyDown | (
(e: KeyboardEvent
)) => void | — | Handler that is called when a key is pressed. |
onKeyUp | (
(e: KeyboardEvent
)) => void | — | Handler that is called when a key is released. |
Accessibility
Name | Type | Default | Description |
aria-label | string | — | Defines a string value that labels the current element. |
aria-labelledby | string | — | Identifies the element (or elements) that labels the current element. |
aria-describedby | string | — | Identifies the element (or elements) that describes the object. |
aria-details | string | — | Identifies the element (or elements) that provide a detailed, extended description for the object. |
Styling#
React Aria components can be styled in many ways, including using CSS classes, inline styles, utility classes (e.g. Tailwind), CSS-in-JS (e.g. Styled Components), etc. By default, all components include a builtin className
attribute which can be targeted using CSS selectors. These follow the react-aria-ComponentName
naming convention.
.react-aria-Link {
/* ... */
}
.react-aria-Link {
/* ... */
}
.react-aria-Link {
/* ... */
}
A custom className
can also be specified on any component. This overrides the default className
provided by React Aria with your own.
<Link className="my-link">
{/* ... */}
</Link>
<Link className="my-link">
{/* ... */}
</Link>
<Link className="my-link">
{/* ... */}
</Link>;
In addition, some components support multiple UI states (e.g. focused, placeholder, readonly, etc.). React Aria components expose states using DOM attributes, which you can target in CSS selectors. These are ARIA attributes wherever possible, or data attributes when a relevant ARIA attribute does not exist. For example:
.react-aria-Link[data-pressed] {
/* ... */
}
.react-aria-Link[data-pressed] {
/* ... */
}
.react-aria-Link[data-pressed] {
/* ... */
}
The className
and style
props also accept functions which receive states for styling. This lets you dynamically determine the classes or styles to apply, which is useful when using utility CSS libraries like Tailwind.
<Link className={({isPressed}) => isPressed ? 'bg-gray-700' : 'bg-gray-600'} />
<Link
className={({ isPressed }) =>
isPressed ? 'bg-gray-700' : 'bg-gray-600'}
/>;
<Link
className={(
{ isPressed }
) =>
isPressed
? 'bg-gray-700'
: 'bg-gray-600'}
/>;
Render props may also be used as children to alter what elements are rendered based on the current state. For example, you could render an extra element when the link is in a pressed state.
<Link>
{({isPressed}) => (
<>
{isPressed && <PressHighlight />}
Press me
</>
)}
</Link>
<Link>
{({isPressed}) => (
<>
{isPressed && <PressHighlight />}
Press me
</>
)}
</Link>
<Link>
{({ isPressed }) => (
<>
{isPressed && (
<PressHighlight />
)}
Press me
</>
)}
</Link>;
The states, selectors, and render props for Link
are documented below.
Name | CSS Selector | Description |
isCurrent | [aria-current] | Whether the link is the current item within a list. |
isHovered | [data-hovered] | Whether the link is currently hovered with a mouse. |
isPressed | [data-pressed] | Whether the link is currently in a pressed state. |
isFocused | :focus | Whether the link is focused, either via a mouse or keyboard. |
isFocusVisible | [data-focus-visible] | Whether the link is keyboard focused. |
isDisabled | [aria-disabled] | Whether the link is disabled. |
Usage#
Router links#
The <Link>
component can wrap a custom link element provided by a router like React Router.
import {Link as RouterLink} from 'react-router-dom';
<Link>
<RouterLink to="/foo">Foo</RouterLink>
</Link>
import {Link as RouterLink} from 'react-router-dom';
<Link>
<RouterLink to="/foo">Foo</RouterLink>
</Link>
import {Link as RouterLink} from 'react-router-dom';
<Link>
<RouterLink to="/foo">
Foo
</RouterLink>
</Link>
Client handled links#
When the content is plain text, a <Link>
is rendered as a <span>
but exposed to assistive technologies as a link. Events will need to be handled in JavaScript with the onPress
prop.
Note: this will not behave like a native link. Browser features like context menus and open in new tab will not apply.
<Link onPress={() => alert('Pressed link')}>Adobe</Link>
<Link onPress={() => alert('Pressed link')}>Adobe</Link>
<Link
onPress={() =>
alert(
'Pressed link'
)}
>
Adobe
</Link>
Events#
Link
supports user interactions via mouse, keyboard, and touch. You can handle all of these via the onPress
prop. This is similar to the standard onClick
event, but normalized to support all interaction methods equally. In addition, the onPressStart
, onPressEnd
, and onPressChange
events are fired as the user interacts with the link.
Each of these handlers receives a PressEvent
, which exposes information about the target and the type of event that triggered the interaction. See usePress for more details.
function Example() {
let [pointerType, setPointerType] = React.useState(null);
return (
<>
<Link
onPressStart={(e) => setPointerType(e.pointerType)}
onPressEnd={(e) => setPointerType(null)}
>
Press me
</Link>
<p>
{pointerType
? `You are pressing the link with a
: !`'Ready to be pressed.'}
</p>
</>
);
}
function Example() {
let [pointerType, setPointerType] = React.useState(null);
return (
<>
<Link
onPressStart={(e) => setPointerType(e.pointerType)}
onPressEnd={(e) => setPointerType(null)}
>
Press me
</Link>
<p>
{pointerType
? `You are pressing the link with a
: !`'Ready to be pressed.'}
</p>
</>
);
}
function Example() {
let [
pointerType,
setPointerType
] = React.useState(
null
);
return (
<>
<Link
onPressStart={(e) =>
setPointerType(
e.pointerType
)}
onPressEnd={(e) =>
setPointerType(
null
)}
>
Press me
</Link>
<p>
{pointerType
? `You are pressing the link with a
: !`'Ready to be pressed.'}
</p>
</>
);
}
Disabled#
A link can be disabled by passing the isDisabled
property. This will work with both native
link elements as well as client handled links. Native navigation will be disabled, and the onPress
event will not be fired. The link will be exposed as disabled to assistive technology with ARIA.
<Link isDisabled>
<a href="https://adobe.com" target="_blank">Disabled link</a>
</Link>
<Link isDisabled>
<a href="https://adobe.com" target="_blank">
Disabled link
</a>
</Link>
<Link isDisabled>
<a
href="https://adobe.com"
target="_blank"
>
Disabled link
</a>
</Link>
Advanced customization#
Hooks#
If you need to customize things further, such as customizing the DOM structure, you can drop down to the lower level Hook-based API. See useLink for more details.