Theme
Sound
Jump to a component
Core · Actions
TextLink
TextLink is a quiet action inside a line or a row of text: Accept, Decline, Why; Ask Maki; Use it.
Live, from @anicanon/sakuga 2.0.0
Sakuga for iOS and Android is coming
iOS
Coming soon
TextLink for iOS is in the roughs. The tokens it will read are the ones on this page, the same on every platform.
Android
Coming soon
TextLink for Android is in the roughs. The tokens it will read are the ones on this page, the same on every platform.
- Use it for
- A quiet action beside what it acts on, inside a line or a row of text (Accept, Decline, Why), and the way into a deletion.
- Not for
- The action a view exists forButton
- An action shown as a glyph aloneIconButton
- A row that opens a pageListRow
Guidelines
hrefmakes it a link, otherwise a button.variant="strong"for the one that matters most in its row.variant="destructive"is the quiet way into a deletion ("Delete my account", "Delete The Winter"), intext-danger. It opens the dialog whoseButton variant="destructive"does the deleting.- It carries a quiet underline at rest, in its own colour at
opacity-muted, so a link in a sentence never depends on colour alone. Under the pointer and with focus the underline takes the link's full colour, and focus adds the ring; it never becomes a filled button. - Use a
Buttonwhen the action is the point of the view; a TextLink when it sits beside what it acts on.
import { TextLink } from '@anicanon/sakuga/ui';
export default function TextLinkExample() {
return (
<>
<TextLink variant="strong">Accept</TextLink>
<TextLink>Decline</TextLink>
<TextLink>Why</TextLink>
<TextLink icon="comment" href="#">
Ask Maki
</TextLink>
<TextLink variant="destructive">Delete my account</TextLink>
</>
);
}PropsTextLinkProps
childrenrequiredReactNodevariant'quiet' | 'strong' | 'destructive'destructive: the quiet way into a deletion ("Delete my account").
hrefstringiconIconNameonClickMouseEventHandleraria-labelstringaria-haspopupboolean | 'dialog' | 'menu' | 'listbox'For a link that opens a dialog or menu.
aria-expandedbooleanaria-controlsstringclassNamestringAn IconName is any of the names Icon lists.
Each token reads a role, and the role lands on a value in each theme. Change the role and every component that reads it follows.
Colour
tlink-fgTextLink: at rest.text-secondaryneutral-800#2e2d36text-secondaryneutral-200#dcdcdetlink-strongTextLink: the strong one in a row.text-primaryneutral-925#0b0a10text-primaryneutral-0#fffffftlink-hoverTextLink: under the pointer.text-primaryneutral-925#0b0a10text-primaryneutral-0#fffffftlink-destructiveTextLink destructive: the quiet way into a deletion.text-dangervermilion-600#c8321etext-dangervermilion-400#ff7a5cSpace and shape
tlink-icon-sizeicon-size-xs14px
tlink-gapgap-xs4px
tlink-hover-underline-offsetunderline-offset3px
tlink-focus-outline-offsetfocus-ring-offset3px
tlink-focus-radiusradius-xs4px
tlink-underline-thicknessline-hairline1px
tlink-underline-offsetunderline-offset3px
tlink-underline-colorits own value
color-mix(in srgb,currentColor calc(0.6 * 100%),transparent)
Type
tlink-fonttext-caption-strong600 13px/18px "Funnel Sans", system-ui, -apple-system, "Segoe UI", sans-serif
Motion
tlink-durationmotion-fast160ms
Checked automatically with axe-core 4.11.4 against WCAG 2.2 A and AA, on the live preview above, in light and dark, on 26 October 2026.
- Result
- No issues found, in light or in dark.
- By design
- A link with
href, otherwise a button: Tab reaches it, Enter activates it (Space too as a button), and a screen reader hears its text oraria-label, with the icon hidden.variantchanges only its look. For a link that opens a dialog,aria-haspopup,aria-expandedandaria-controlspass through. Its underline at rest tells it apart from the text around it without colour (WCAG 1.4.1). - Not tested
- The automated check doesn't test keyboard use, focus order or what a screen reader says. The lines above are the design system's own account of them.