Link
A destination stated as text, the anchor every navigation component in the framework renders.
A link is a destination a reader can enter, and the framework's navigation components render
every one of their destinations through this component: a navbar's links, a footer's columns and
a breadcrumb's steps are all Links. That is why it is worth understanding on its own, the
emphasis axes, the external handling and the substitution are stated once, here, and inherited
everywhere.
It renders a real anchor with a real destination. What it adds is a vocabulary for how loudly the link speaks, and an explicit statement of whether it leaves the site.
Usage
import { Link } from "@asheeui/web";
<Link href="/invoices">All invoices</Link>;
isExternal is the one prop that changes behaviour rather than appearance: it sets the target
and relationship attributes an off-site destination needs and shows the affordance that says so.
Emphasis
Three axes, each with a default. variant says how much the link asks for, default, muted
for navigation beside content, or subtle for a link inside a sentence that is already quiet.
color is a role rather than a hex value. underline decides when the line appears: always
for a link inside a run of text, hover for a link that is already recognisable, and never for
one whose surroundings carry the meaning. size is the fourth: it scales the text and the icons
beside it, so a link in a caption does not keep the size of a heading.
<Link href="/invoices" variant="muted" underline="always">
March invoices
</Link>
The anchor it renders
Some props belong to the anchor rather than to the text. isExternal gives it the target and the
relationship, and draws the external mark after the label; endIcon replaces that mark with
content of your own. disabled refuses the press, states the condition with aria-disabled and
drops the destination, so a link that is temporarily unreachable cannot be followed by accident.
Framework routers
TanStack Router and React Router name a destination to, not href. Both spellings are accepted:
// A plain anchor, no router involved.
<Link to="/components">Components</Link>
// The same call site, routed by TanStack.
<Link to="/components" component={RouterLink}>Components</Link>
With component set, to is forwarded to it, so the router handles the navigation as it would for
any of its own links, and href is not passed, because a router link that receives both has two
destinations. Without component, to becomes the anchor's href, which means a page can be written
before the router exists and keep working after it is introduced. When both props are given, to wins.
Then there is component, which replaces the element: pass a framework's router link and its
props and the link renders that instead, receiving the destination, the classes, the state and
the press handler an anchor would have received. componentProps is merged last, so it takes
precedence over the props the framework passes itself.
The substitution is the framework's shared seam rather than a Link feature: it is the same
contract Image and Form use, and it is described in
links and substitution.
Props
size, underline and isExternal are registered by the component as md, hover and
false, so each resolves from the instance, then components.link, then that value. variant
is not registered and falls back to default: the application's defaultVariant describes a
control's surface, and a link has no surface. color is not registered either, it resolves
from the application's defaultColor and then primary, which is what keeps a link the same
accent as the button beside it.
Accessibility
- The element is a real
<a href>, so it is in the tab order and in the reading order without atabindex, it is announced as a link, and it can be opened in a new tab or copied as a URL. The focus ring is drawn withfocus-visible, so it appears for a keyboard and not for a mouse. isExternalsetstarget="_blank"withrel="noopener noreferrer", so an off-site destination neither takes the page's context away silently nor keeps a handle on it.- Icon slots are presentational wrappers around the content you pass: the link's accessible name
is its text, so a link whose only content is an icon needs its own
aria-label. disabledstates the condition witharia-disabledand dims the text rather than hiding it. Thehrefis kept, so the element is still announced as a link and still reachable by keyboard, the press is what is refused, not the existence of the destination. A control that vanishes from the tab order is one a reader cannot be told about.
A substituted component receives aria-current and aria-disabled the same way an anchor does,
which is what lets the navigation components mark the current page through it: see
links and substitution.