TextLink

A link in the accent colour, inside a sentence or on its own.

Overview

A link that sits in text. A link that is an action is a ButtonLink.

In sentence

Do

Questions? Email [email protected], or read the terms first.

import { Body, TextLink } from "@hackcove/ui";

<Body as="p">
  Questions? Email <TextLink href="mailto:[email protected]">[email protected]</TextLink>, or
  read the <TextLink href="#terms">terms</TextLink> first.
</Body>
A link in running text is a TextLink inside a Body.
Don't

Questions? Email [email protected], or read the terms first.

import { Body } from "@hackcove/ui";

<Body as="p">
  Questions? Email <a href="mailto:[email protected]">[email protected]</a>, or read the{" "}
  <a href="#terms">terms</a> first.
</Body>
A bare <a> has none of the theme's link colour, weight or focus ring.

External

Do
import { TextLink } from "@hackcove/ui";

<TextLink href="https://example.com" external>
  example.com
</TextLink>
external opens another site in a new tab and adds rel="noreferrer" with it.
Don't
import { TextLink } from "@hackcove/ui";

<TextLink href="https://example.com" target="_blank">
  example.com
</TextLink>
target="_blank" by hand leaves out the rel. Say external and the link gets both.

Router

Do
import { TextLink } from "@hackcove/ui";

<TextLink render={(p) => <a href="#terms" {...p} />}>Read the terms</TextLink>
In an app with a router, render draws the router's own <Link>; here an anchor stands in.

Stretch

Do
import { Card, TextLink } from "@hackcove/ui";

<Card title="Quote 12">
  <TextLink href="#quote-12" stretch>
    Open the quote
  </TextLink>
</Card>
stretch makes the whole of the nearest relative ancestor the click target: a Card here, a TableRow in a table.

Usage

  • Use TextLink for every link in running text. Never a bare <a>.
  • external is for another site: it opens a new tab with rel="noreferrer".
  • In an app with a router, render draws the router's own <Link>: render={(p) => <Link to="/terms" {...p} />}. The library has no router.
  • size pins the type size to xs or sm; left out, the link takes the size of its text. mono sets the monospace face for a path or an id.
  • tone gives the link a meaning's colour (warn, danger, positive, info, muted), underlined on hover. Use it for a link that is the message, like "3 failed".
  • stretch makes the nearest relative ancestor the click target: a Card or a TableRow. Put it on the one link in that row.
  • A router's own <Link> that must look like a TextLink takes linkClass, and a stretched one linkStretchClass as well.

Accessibility

  • A TextLink is a native <a>, so it is in the tab order and opens with Enter.
  • It has a focus ring from the component, so the keyboard focus is always visible.
  • external sets target="_blank" and rel="noreferrer".
  • Every anchor prop (aria-*, download, title, a handler) goes on the <a>; render receives them as well.

API

TextLink

An inline text link in the accent colour. Every anchor prop goes on the <a>. With render it draws the app's own router <Link> instead (render={(p) => <Link to="/terms" {...p} />}). size pins the type size (xs or sm), tone gives it a meaning's colour and mono sets the monospace face.


external

Opens in a new tab: adds target="_blank" and rel="noreferrer".

Type
boolean
Default
false

href
Type
string

mono

The monospace face, for a path, an id or a command.

Type
boolean
Default
false

render
Type
LinkRender

size

The link's own type size. Left out, it takes the size of the text around it.

Type
"sm" | "xs"

stretch

The link covers its nearest relative ancestor, so the whole row or card is the click target.

Type
boolean
Default
false

tone

A meaning's colour, as on the inline roles: warn for a warning link, danger, positive, info or muted. Left out, the link is the accent colour.

Type
"positive" | "danger" | "info" | "warn" | "muted"

Functions

  • linkClass The classes of an inline text link, for a router's own <Link> that must look like a TextLink.
  • linkStretchClass Stretches a link's hit area over its nearest relative ancestor, so a whole row or card opens it; add it to the one link in the row.