Link

Navigates to another page, screen, or location. Always underlined, always a real link, so the destination is exposed to assistive technology and to the platform.

Basic usage

Install the package:

pnpm add @design-schema/react @design-schema/tokens

Import the stylesheet once for the app, then the component:

import '@design-schema/tokens/calm-precise/css';
import '@design-schema/react/index.css';
import { Link } from '@design-schema/react';

Examples

Props

6 rows
PropTypeDefaultDescriptionPlatforms
href requiredstring—

The destination. A URL on web; a URL or app route on native, resolved by `onPress` when the consumer provides it.

web, lit, rn, swiftui
label requiredstring—

The link text. Also the accessible name. Says where the link goes, not "click here".

web, lit, rn, swiftui
externalbooleanfalse

Opens the destination in a new tab or the system browser and appends `copy.externalSuffix` to the accessible name, with a decorative trailing icon.

Accessibility: Users are told the link leaves the current context before they activate it (WCAG 3.2.5 advisory, G201).

web, lit, rn, swiftui
tonedefault | inheritdefault

`default` uses the link colors. `inherit` takes the surrounding text color and relies on the underline alone — for links inside muted or on-action text. Under `inherit` the color, colorHover and colorVisited bindings are not applied: rest, hover, visited and (on native) pressed all resolve to the inherited color (currentColor on web and Lit, the enclosing TextStyleContext color on native), and the underline and the external icon follow that same color, so an inherited link has no hover or visited color change by design. On web the root takes `color: inherit`, and the color, :visited and :hover rules are scoped to the `tone: default` modifier. On native Link sets no textDecorationColor under either tone (the underline takes the Text color, so it follows the animated label colour), and under `inherit` the label runs no press animation, since rest and pressed resolve to the same colour; a standalone inherit link outside any system Text has nothing to inherit, so its label and icon both use color.foreground.

web, lit, rn, swiftui
downloadbooleanfalse

Downloads the resource instead of navigating, under the server's file name (a custom file name is out of scope). Web only.

web, lit
currentbooleanfalse

The link points at the page the user is on, in a navigation list (a SidePanel drawer, a Tree of href nodes): `aria-current="page"` on the anchor on web and Lit, `accessibilityState.selected` on React Native (with the `aria-current="page"` mirror on react-native-web, which drops accessibilityState), `.isSelected` on SwiftUI. The link stays a link and keeps its colours and underline; how a navigation also marks it visually is that container's to say. False writes nothing, so an `aria-current` a consumer passes through `...rest` on web (a `step` or `location`) still applies; while `current` is true the prop wins.

Accessibility: The current page is announced, not shown by position or colour alone (WCAG 1.3.1, 4.1.2).

web, lit, rn, swiftui

Events

1 row
EventTypeDescriptionPlatforms
onPressonClick / click / onPress / action

Fired when the link is activated. On web the default navigation still happens unless the consumer prevents it; on native the consumer must navigate (the system opens URLs with Linking when no handler is given). On Lit the name is the native anchor's own `click`, retargeted out of the shadow root — Link emits no `press` CustomEvent. Cancelling: on web the handler receives the click event and cancels navigation with preventDefault or by returning `false` (typed `(event) => void | boolean`; Link calls preventDefault on `false`); on Lit the consumer calls preventDefault on the click; on native the handler receives `href` and returning `false` cancels the Linking hand-off, the only default action native has. `fires: [user]` means Link never dispatches it itself; on web and Lit a script calling `.click()` on the anchor still fires it, as on any link, and Link does not try to filter that out.

web, lit, rn, swiftui

Accessibility

Decisions this component leaves to you

Supply an accessible name. This component has no text of its own to fall back on, so without one a screen reader announces its role and nothing else.

Implicit ARIA role: link.

Anatomy

anchorlabelexternalIcon

What generation guarantees

Accessible name — Every instance carries a programmatic name. Where the component has no text of its own to use, the name is a prop the consumer supplies.

Visible focus — Keyboard focus is always drawn, from the theme’s focus tokens, and is never removed.

Keyboard operable — Everything the pointer can do here, the keyboard can do — see the keyboard section.

Contrast — Text and meaningful non-text contrast meets WCAG AA; the pairs are listed below.

Contrast pairs

3 rows
ForegroundBackgroundLevel
color.linkcolor.backgroundAA
color.link.hovercolor.backgroundAA
color.link.visitedcolor.backgroundAA

This component does not animate, so it has no reduced-motion behaviour to describe.