AvesraAvesrabeta

Link

A styled anchor for navigation with built-in icon support. Apply av-link to a native <a> and optionally av-link-icon for the default arrow icon.

Import

import { AvLinkImports } from '@avesra/angular';

Usage

import { Component } from '@angular/core';
import { AvLinkImports } from '@avesra/angular';

@Component({
  selector: 'app-link-basic-demo',
  imports: [AvLinkImports],
  template: `<a av-link href="#">
  Call to action
  <span av-link-icon></span>
</a>`,
})
export class LinkBasicDemo {}

Anatomy

Import the Link parts and compose them with attribute selectors on <a> and <span> hosts.

<a av-link href="#">
  Call to action
  <span av-link-icon></span>
</a>

Icon Placement

Place av-link-icon before or after the link text. The default icon adds automatic spacing when placed after the label.

import { Component } from '@angular/core';
import { AvLinkImports } from '@avesra/angular';

@Component({
  selector: 'app-link-icon-placement-demo',
  imports: [AvLinkImports],
  template: `<div class="flex flex-col gap-3">
      <a av-link href="#">
        Icon at end (default)
        <span av-link-icon></span>
      </a>
      <a av-link class="gap-1" href="#">
        <span av-link-icon></span>
        Icon at start
      </a>
    </div>`,
})
export class LinkIconPlacementDemo {}

Text Decorations with Tailwind CSS

Link is underlined on hover by default. Use the underline input for the common modes, or pass Tailwind text-decoration utilities to customize color, style, thickness, and offset.

import { Component } from '@angular/core';
import { AvLinkImports } from '@avesra/angular';

@Component({
  selector: 'app-link-underline-and-offset-demo',
  imports: [AvLinkImports],
  template: `<div class="flex flex-col gap-6">
      <div class="flex flex-col gap-2">
        <p class="text-sm font-medium text-muted">Default hover underline</p>
        <a av-link href="#">
          Hover to see the underline
          <span av-link-icon></span>
        </a>
      </div>

      <div class="flex flex-col gap-2">
        <p class="text-sm font-medium text-muted">Always visible underline</p>
        <a av-link underline="always" href="#">
          Underline always visible
          <span av-link-icon></span>
        </a>
      </div>

      <div class="flex flex-col gap-2">
        <p class="text-sm font-medium text-muted">No underline</p>
        <a av-link underline="none" href="#">
          Link without any underline
          <span av-link-icon></span>
        </a>
      </div>

      <div class="flex flex-col gap-2">
        <p class="text-sm font-medium text-muted">Changing the underline offset</p>
        <div class="flex flex-col gap-3">
          <a av-link class="underline-offset-1" href="#">
            Offset 1 (1px space)
            <span av-link-icon></span>
          </a>
          <a av-link class="underline-offset-2" href="#">
            Offset 2 (2px space)
            <span av-link-icon></span>
          </a>
          <a av-link class="underline-offset-4" href="#">
            Offset 4 (4px space)
            <span av-link-icon></span>
          </a>
          <a av-link class="underline-offset-8" href="#">
            Offset 8 (8px space)
            <span av-link-icon></span>
          </a>
        </div>
      </div>
    </div>`,
})
export class LinkUnderlineAndOffsetDemo {}

Underline line (underline input):

  • always — Always visible underline
  • none — Remove underline (including hover)
  • hover (default) — Underline appears on hover

Text decoration color:

  • decoration-accent, decoration-muted, etc. — Set underline color using theme colors
  • decoration-muted/50 — Use opacity modifiers for semi-transparent underlines

Text decoration style:

  • decoration-solid — Solid line (default)
  • decoration-double — Double line
  • decoration-dotted — Dotted line
  • decoration-dashed — Dashed line
  • decoration-wavy — Wavy line

Text decoration thickness:

  • decoration-1, decoration-2, decoration-4, etc. — Control underline thickness

Underline offset:

  • underline-offset-1, underline-offset-2, underline-offset-4, etc. — Adjust spacing between text and underline

For more details, see the Tailwind CSS documentation:

Available BEM classes:

  • Base: av-link
  • Icon: av-link__icon

Custom Icon

Project a custom SVG (or other icon) inside av-link-icon to replace the default arrow.

import { Component } from '@angular/core';
import { AvLinkImports } from '@avesra/angular';

@Component({
  selector: 'app-link-custom-icon-demo',
  imports: [AvLinkImports],
  template: `<div class="flex flex-col gap-3">
      <a av-link href="#">
        External link
        <span av-link-icon class="ml-1.5 size-3">
          <svg
            xmlns="http://www.w3.org/2000/svg"
            viewBox="0 0 24 24"
            fill="none"
            stroke="currentColor"
            stroke-width="2"
            stroke-linecap="round"
            stroke-linejoin="round"
            aria-hidden="true"
          >
            <path d="M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6" />
            <polyline points="15 3 21 3 21 9" />
            <line x1="10" y1="14" x2="21" y2="3" />
          </svg>
        </span>
      </a>
      <a av-link class="gap-1" href="#">
        Go to page
        <span av-link-icon class="size-3">
          <svg
            xmlns="http://www.w3.org/2000/svg"
            viewBox="0 0 24 24"
            fill="none"
            stroke="currentColor"
            stroke-width="2"
            stroke-linecap="round"
            stroke-linejoin="round"
            aria-hidden="true"
          >
            <path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71" />
            <path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71" />
          </svg>
        </span>
      </a>
    </div>`,
})
export class LinkCustomIconDemo {}

Variants

Set variant on av-link — primary (default link color), secondary (foreground), or muted.

import { Component } from '@angular/core';
import { AvLinkImports } from '@avesra/angular';

@Component({
  selector: 'app-link-variants-demo',
  imports: [AvLinkImports],
  template: `<div class="flex flex-wrap items-center gap-4">
      <a av-link href="#">
        Primary link
        <span av-link-icon></span>
      </a>
      <a av-link variant="secondary" href="#">
        Secondary link
        <span av-link-icon></span>
      </a>
      <a av-link variant="muted" href="#">
        Muted link
        <span av-link-icon></span>
      </a>
    </div>`,
})
export class LinkVariantsDemo {}

Styling

Passing Tailwind CSS classes

Pass utility classes on the host <a av-link> element.

import { Component } from '@angular/core';
import { AvLinkImports } from '@avesra/angular';

@Component({
  selector: 'app-link-custom-styling-demo',
  imports: [AvLinkImports],
  template: `<a
  av-link
  class="text-lg font-bold text-accent hover:text-accent/80"
  href="#"
>
  Custom styled link
</a>`,
})
export class LinkCustomStylingDemo {}

Customizing the component classes

To customize the Link classes, use the @layer components directive. Learn more.

@layer components {
  .av-link {
    @apply font-semibold;
  }
}

Avesra follows the BEM methodology so component variants and states stay reusable and easy to customize.

CSS Classes

The Link component uses these CSS classes:

Base Classes

  • .av-link — Base link styles
  • .av-link__icon — Link icon styles

Variant Classes

  • .av-link--secondary — Foreground text color
  • .av-link--muted — Muted text color
  • .av-link--underline-always — Always underlined
  • .av-link--underline-none — No underline

Interactive States

The component supports both CSS pseudo-classes and data attributes:

  • Focus::focus-visible or [data-focus-visible="true"]
  • Hover::hover or [data-hovered="true"]
  • Pressed::active or [data-pressed="true"]
  • Disabled:[aria-disabled="true"] or [data-disabled="true"]
  • External:[data-external="true"]

API

Props for a[av-link]. Content is projected as children. span[av-link-icon] has no inputs — omit children for the default arrow, or project a custom icon.

PropTypeDefaultDescription
hrefstring'#'Destination URL for the anchor.
variant'primary' | 'secondary' | 'muted''primary'Visual style variant.
underline'always' | 'hover' | 'none''hover'Underline display behavior.
disabledbooleanfalseDisables pointer and keyboard navigation (removes href, sets aria-disabled).
externalboolean—Opens in a new tab. Auto-detected for http(s), mailto:, and tel: when omitted.
targetstring—Controls where to open the linked document (defaults to _blank when external).
relstring—Relationship between the current and linked documents (defaults to noopener noreferrer for _blank).

Using with Angular Router

Compose av-link with routerLink on the same <a> host:

import { Component } from '@angular/core';
import { RouterLink } from '@angular/router';
import { AvLinkComponent, AvLinkIconComponent } from '@avesra/angular';

@Component({
  selector: 'app-nav-link',
  imports: [RouterLink, AvLinkComponent, AvLinkIconComponent],
  template: `
    <a av-link routerLink="/about">
      About Page
      <span av-link-icon></span>
    </a>
  `,
})
export class NavLink {}

Or apply Link styles via avLinkClasses / avLinkIconClasses when you need a plain router link without the directive:

import { Component } from '@angular/core';
import { RouterLink } from '@angular/router';
import { avLinkClasses, avLinkIconClasses } from '@avesra/angular';

@Component({
  selector: 'app-styled-router-link',
  imports: [RouterLink],
  template: `
    <a [routerLink]="'/about'" [class]="linkClasses">
      About Page
      <span [class]="iconClasses" aria-hidden="true">
        <!-- icon markup -->
      </span>
    </a>
  `,
})
export class StyledRouterLink {
  readonly linkClasses = avLinkClasses({ variant: 'primary', underline: 'hover' });
  readonly iconClasses = avLinkIconClasses();
}

Direct Class Application

Since Avesra uses BEM classes, you can apply Link styles directly to any anchor:

<!-- Apply BEM classes directly with Tailwind utilities -->
<a href="/about" class="av-link underline-offset-2">
  About Page
</a>

<!-- Or with a native anchor and icon slot class -->
<a
  href="/about"
  class="av-link underline decoration-accent underline-offset-4"
>
  About Page
  <span class="av-link__icon" aria-hidden="true"><!-- icon --></span>
</a>

Made with ❤ by SyntaxHertz. Open source and available on GitHub.