Skip to the content

Kongens Nytorv

Metro M1, M2 and M3.

Variants and states

Props

NameTypeDefaultDescription
hrefstring—Where the link goes: a URL or a path. Give it on every Link, unless render gives a router's link that brings its own destination.
childrenReactNode—The link's words, which name where it goes: "Rejseplanen", "Show all departures". Phrasing content only. Required in practice: a link with no words has no name.
classNamestring—Reaches the root; className is merged after pn-Link.
styleCSSProperties—Reaches the root; className is merged after pn-Link.
refRef<HTMLAnchorElement>—Reaches the root element.
hrefstring, default —
Where the link goes: a URL or a path. Give it on every Link, unless render gives a router's link that brings its own destination.
childrenReactNode, default —
The link's words, which name where it goes: "Rejseplanen", "Show all departures". Phrasing content only. Required in practice: a link with no words has no name.
classNamestring, default —
Reaches the root; className is merged after pn-Link.
styleCSSProperties, default —
Reaches the root; className is merged after pn-Link.
refRef<HTMLAnchorElement>, default —
Reaches the root element.

Use it

import { Link } from '@mylder/perron'

Ask your agent

search_docs({ query: "Link" })

Keyboard and ARIA

From the browser's native link and Base UI's useRender, which adds no behaviour. "From" says who does it. The Default story's play presses every key in this table.

KeyDoesFrom
TabMoves focus to the link, in document orderThe browser
Shift+TabMoves focus back out of the link, to the element before itThe browser
EnterFollows the link: fires onClick, then goes to href unless the click is preventedThe browser
SpaceNothing to the link: Space scrolls the page, as on every link, and never follows itThe browser
ElementRoleAccessible name fromStates announced
rootlink, native, from <a href>Its text content, the caller's children; aria-label or aria-labelledby from the caller winVisited, by the browser; aria-current when the caller sets it

What axe won't catch, from the contract, each with how this component meets it:

  • Everything the eye is told, the ear is told, for every shape each prop accepts: the underline tells the eye it is a link and the link role tells the ear; its words are its name; its colour is the text's, so it tells nothing the text doesn't.
  • Every landmark and named region has an accessible name: none here; a link is neither.
  • Every default label can be overridden: none here; Link owns no strings.
  • Every shape the type accepts renders, in every variant: children renders a string, an element and a list alike, in every State, alone or in running text, over one line or several.
  • A hidden copy kept for animation is aria-hidden, and a collapsed region is inert: none here; Link keeps no hidden copy and collapses nothing.
  • Native semantics first: a native <a href>, never role="button" and never Base UI's Button (CR-1); a render element renders an <a> too.
  • Focus moves in reading order and returns on close: the link is one tab stop where it sits in the text, and opens nothing of its own to return from.
  • Every target is at least size.target-min square: Link adds no padding or minimum height of its own, so in running text it meets WCAG 2.2's target size (2.5.8) by its inline exception, and standing alone by its spacing exception, the caller giving it size.target-min of room as Accessibility allows. Padding on an inline run would overlap the lines above and below it, and a minimum height doesn't apply to an inline box; a standalone link in typography.body is 21 px tall, under size.target-min (24 px), so the room around it is the caller's, said in Do and don't.
  • Loops stop when the system asks for less motion: none here; Link has no loop and no transition.

Owned strings

No owned strings: every word comes from the caller, as children.

Link, like LinkButton, owns no "Opens in a new tab" string, draws no external-link icon and takes no external prop, leaving target and rel to the caller. Content design gives no rule on links or new tabs, so the answer LinkButton's spec gives stands for both: a link that leaves Mylder names its destination in its words ("Rejseplanen"), and Mylder's own links open in the same tab. A caller who opens a new tab passes target="_blank" with rel="noopener noreferrer", and both reach the <a> as they are. An owned string and icon can join later, as a new optional prop, without a break, and LinkButton would take the same.

Do and don't

For a caller using the component, with the reason. Each row is a rule: a must row's Don't is never right, a should row's needs a reason, and Checked by says what catches the Don't in a caller's code.

RuleLevelDoDon'tChecked by
DD-1shouldUse Link for a link in text, in a sentence or standing alone, and LinkButton for one shaped like a buttonPut a LinkButton in running text: its height and padding break the linereview
DD-2mustUse Link when pressing it goes somewhere: another page, another place in the app, another siteUse Link to run an action, such as showing a line or closing a panel, with an onClick that prevents the link: that is a Buttonreview
DD-3mustName where it goes, in the words of the sentence: "Departures from Rejseplanen", "Show all departures"Write "Click here", "Read more" or a bare URL: the link's words are all a screen reader hears of it in a list of links (WCAG 2.2, 2.4.4 Link purpose)review
DD-4mustSet the colour and type on the text around the link, and let Link take themRecolour a Link in the brand yellow or a status colour on its own: brand is never a link (Intents), and the text's colour already carries any meaningreview
DD-5mustGive a standalone link size.target-min of room, such as a row of that height or a gap around itSet a standalone link against another target, where a 21 px line leaves too small a mark to pressreview
DD-6mustGive a router's link through render, such as render={<RouterLink to="/departures" />}, so the app's navigation runsWrap a Link in a router link, or a router link in a Link: two nested <a> elements are invalid and make two tab stopsreview
DD-7mustName a site the link leaves Mylder for, and keep Mylder's own links in the same tabOpen a new tab without saying where the link goesreview
DD-8mustLeave a link out when there is nowhere to go yetRender a Link without href or render, or fake a disabled one with opacity: an <a> with no href is not a link, and disabled is a colourreview