Skip to content
EspañolEnglish
All components (204)

Button-style link

Actions · ButtonLink

What it is and when to use it

What navigates is a link, even if it is painted as a button. ButtonLink looks like Button (the same variants, tones and sizes) and is a real <a>: it opens in another tab with a middle click, the address can be copied and the screen reader says "link".

When to use it

  • The call that leads to another screen: "View order", "Go to checkout", "Keep shopping".
  • At the foot of a card, a notice or an empty state, when the way out is another page.

When not to

  • If it does something on the same screen (save, delete, open a dialog), it is a Button. A <button> that navigates through code does not open in another tab or get announced as a link.
  • A link inside a paragraph stays a text link: Link.
  • Several destinations gathered in a menu: ActionMenu with href on each action.

Keyboard: Tab reaches it; Enter follows it. Space does not, as with any link. With disabled it no longer leads anywhere: it is still announced as a link, with aria-disabled, and leaves the Tab order. With RouterProvider, the href goes through the application's router, as in Link.

Accessibility: the name is the text; icons are decorative. If it opens in another tab (target="_blank"), say so in the name with an aria-label that starts with the visible text.

Fine-tuning: the --amset-button-* variables of Button; its own class is amset-button--link.

What it looks like

<ButtonLink href="/componentes/" variant="solid">View all components</ButtonLink>
<ButtonLink href="/empezar/" variant="outline">Getting started</ButtonLink>
<ButtonLink href="https://ui.amset.tech" variant="ghost">Open the test bench</ButtonLink>

Props

Import it with import { ButtonLink } from '@amset/ui'. Required props are marked.

PropTypeWhat it does
childrenrequiredReactNode—
classNamestring—
disabledbooleanTurned off: it stops navigating and entering the tab order, and is announced that way.
endIconReactNodeIcon after the text (an arrow, a menu chevron).
fullWidthbooleanTakes up the whole available width. On mobile this is usually what you want.
hrefstringWhere it leads. Without it, it is not a link: it is a button.
onPress() => voidCalled on press, with mouse or keyboard, in addition to navigating. Without an argument, as on the text link: whatever needs stopping is stopped with `onClick`, which DOES carry the real event there.
shape"default" | "pill"The shape: `default` (the default) or `pill`, with fully rounded corners. Inside a `ButtonGroup` only the outer corners of the group are rounded. For the round icon-only button, `IconButton`.
size"sm" | "md" | "lg"—
startIconReactNodeIcon before the text. Decorative: the text is what counts.
styleCSSPropertiesInline style. The stable look goes in the `--amset-button-*` CSS variables, which is what is maintained; this is for what is only known at run time: a colour chosen by whoever uses the application, a calculated position, a height that depends on the content. It used to be forbidden and had to be opened: a real front end used it on 40 buttons to calculate their halo from an arbitrary colour (AMS-735), and without it the only way out was to write CSS by hand against our classes.
tone"neutral" | "accent" | "secondary" | "tertiary" | "info" | "success" | "warning" | "error"What it means. Without it, a solid or soft button is `accent` (the main action) and an outline or ghost one is `neutral`. `error` is the one for deleting or cancelling an account.
variant"solid" | "soft" | "outline" | "ghost"How it is drawn: `solid`, `soft`, `outline` (default) or `ghost`.

It also accepts the attributes of the element it renders: className, style, data-*, aria-* and its events.

In the test bench

Every state and variant, to try one at a time, on its page at ui.amset.tech: