# Link

An accessible inline link. Renders an `<a>` element with theme-aware colour, optional underline, and automatic security attributes for external targets.
<!-- BEGIN:xui-mcp-instructions:link -->
An inline interactive text element that navigates the user to another location or triggers a related action. Renders as styled text with optional leading and trailing icons. Used inside body copy, lists, form helper text, and any context where navigation or a contextual action should blend with surrounding text rather than stand out as a button.

### When to use
- For in-text navigation links — e.g. *"Read our [Privacy Policy]"*, *"See [all results]"*
- For contextual actions inside helper text, empty states, or notifications — e.g. *"[Resend code]"*, *"[Clear filters]"*, *"[Learn more]"*
- When the action is secondary and should not visually compete with a primary Button
- In breadcrumbs, footers, settings descriptions, and legal text where navigation is part of the prose

### When not to use
- As a primary call-to-action — use a Button
- When the interaction triggers an operation (save, delete, submit) rather than navigating — use a Button or Flex button
- For standalone navigation items in a menu or sidebar — use a Navigation component
- When the link needs a container, padding, or icon-only format — use a Flex button

### Content guidelines
- Descriptive text — link labels must make sense out of context. Screen readers often navigate by listing all links on a page. Labels like *"here"*, *"this"*, or *"more"* are meaningless in isolation.
- Action links — use an imperative verb phrase: *"Resend code"*, *"Clear filters"*, *"View all"*, *"Download report"*.
- Navigation links — use the destination name or a descriptive noun phrase: *"Privacy Policy"*, *"API reference"*, *"Account settings"*.
- Avoid punctuation — do not include trailing commas, periods, or colons inside the link text. Place punctuation outside the link: *"See our [FAQ]."* not *"See our [FAQ.]"*
- Capitalisation — use sentence case for action links (*"View all results"*). Use title case only for proper names and document titles (*"Terms of Service"*, *"Privacy Policy"*).

### Behaviour guidelines
- Navigation vs action — use Link for navigation (opening a URL, switching routes) and for lightweight text-level actions (resend, clear, show more). For operations that change state on the server (delete, publish, submit), use a Button even if it is visually small.
- External links — when a link opens in a new tab, always add a Right icon (external link symbol ↗) and include target=*"_blank"* with rel=*"noopener noreferrer"*. Inform screen reader users by including visually hidden text: *"(opens in new tab)"*, or include it in the aria-label.
- Visited state — style :visited links distinctly in contexts where the browsing history is meaningful (documentation, article indexes). Do not override :visited styles in application UI where it adds no value.
- Disabled links — avoid disabled links. If an action is not available, either remove the link entirely or replace it with plain text. If a disabled link is unavoidable, use aria-disabled=*"true"* and tabindex=*"-1"* rather than the disabled attribute (which does not exist on <a> elements).
- Text length — keep link text concise and descriptive. A link labelled *"here"* or *"click here"* is meaningless out of context and inaccessible. The link text should describe the destination or action: *"View invoice #1042"*, *"Reset password"*, *"Download CSV"*.
- Underline — Link text must be distinguishable from surrounding non-link text by more than colour alone (WCAG 1.4.1). Use an underline, heavier weight, or other non-colour cue in addition to the palette colour.

### Accessibility
- Link must be implemented as a native <a href=*"…"*> element — not a <div>, <span>, or <button> with a click handler. Native <a> elements are keyboard-focusable, announced as links by screen readers, and support right-click context menus.
- The link must have a descriptive accessible name. If the visible text is not descriptive enough (e.g. it reads *"here"* in context), add aria-label with a more descriptive label.
- External links must include aria-label or visually hidden text announcing that they open in a new tab: e.g. aria-label=*"API reference (opens in new tab)"*.
- The focus state must have a visible :focus-visible ring that meets WCAG 2.4.7 (Focus Visible). Do not suppress the browser's default focus ring without providing a custom replacement.
- Do not rely on colour alone to distinguish links from surrounding text (WCAG 1.4.1). Always use an underline or weight change in addition to the palette colour.
- Icon-enriched links where the icon is decorative must have aria-hidden=*"true"* on the icon element so screen readers do not announce icon names.
- Visited links in informational contexts (docs, knowledge base) should have a distinct :visited colour to help users track what they have already read.
<!-- END:xui-mcp-instructions:link -->

## Installation

```bash
npm install @xsolla/xui-link
```

## Imports

```tsx
import { Link } from '@xsolla/xui-link';
```

## Quick start

```tsx
import * as React from 'react';
import { Link } from '@xsolla/xui-link';

export default function Example() {
  return <Link href="https://example.com">Visit Example</Link>;
}
```

## API Reference

### `<Link>`

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `children` | `ReactNode` | - | Link content. |
| `href` | `string` | - | Destination URL. Cleared when `disabled`. |
| `onClick` | `() => void` | - | Click handler. When provided, `preventDefault()` is called before invoking — browser navigation via `href` is suppressed, so handle navigation yourself (e.g. router push). `href` remains on the `<a>` for right-click and assistive tech. |
| `target` | `string` | - | Anchor target (e.g. `'_blank'`). When `'_blank'`, `rel="noopener noreferrer"` is added automatically and merged with any caller-supplied `rel`. |
| `rel` | `string` | - | Additional `rel` tokens. |
| `size` | `'sm' \| 'md' \| 'lg'` | `'md'` | Font size preset (12/14/16px). |
| `underline` | `boolean` | `false` | Underline the text. |
| `disabled` | `boolean` | `false` | Removes `href`, sets `tabIndex={-1}`, and shows `not-allowed` cursor. |
| `color` | `string` | theme `control.link.primary` | Custom text colour (ignored when `disabled`). |
| `testID` | `string` | - | Test identifier. |

Inherits `ThemeOverrideProps` (`themeMode`, `themeProductContext`).

## Examples

### Sizes

```tsx
import * as React from 'react';
import { Link } from '@xsolla/xui-link';

export default function Example() {
  return (
    <div style={{ display: 'flex', flexDirection: 'column', gap: 8 }}>
      <Link size="sm" href="#">Small Link</Link>
      <Link size="md" href="#">Medium Link</Link>
      <Link size="lg" href="#">Large Link</Link>
    </div>
  );
}
```

### External link

```tsx
import * as React from 'react';
import { Link } from '@xsolla/xui-link';

export default function Example() {
  return (
    <Link href="https://example.com" target="_blank">
      Open in a new tab
    </Link>
  );
}
```

### Underlined inline link

```tsx
import * as React from 'react';
import { Link } from '@xsolla/xui-link';

export default function Example() {
  return (
    <p>
      Read our <Link href="/terms" underline>Terms of Service</Link> and{' '}
      <Link href="/privacy" underline>Privacy Policy</Link>.
    </p>
  );
}
```

### Disabled

```tsx
import * as React from 'react';
import { Link } from '@xsolla/xui-link';

export default function Example() {
  return (
    <Link href="/disabled" disabled>
      Disabled Link
    </Link>
  );
}
```

## Accessibility

- Renders a native `<a>` with explicit `role="link"`.
- Disabled links lose their `href` and become unfocusable (`tabIndex={-1}`).
- Visible focus ring uses the theme's brand border colour.
- For `target="_blank"`, `rel="noopener noreferrer"` is enforced automatically.
- Use descriptive link text — avoid generic phrases like "click here".
