# Link Component

A simple, semantic link component for wrapping content (text, icons, images) with clickable links. Designed for minimal visual styling while maintaining accessibility and flexibility.

## Import path
```tsx
import Link from '@hubspot/cms-component-library/Link';
```

## Purpose

The Link component provides a lightweight wrapper for making content clickable without the visual weight of a button. It's distinct from the Button component in both purpose and appearance:

- **Link**: Simple content wrapper with minimal styling (this component)
- **Button**: Visual UI button with prominent styling (use even when the button functions as a link)

## When to Use Link vs Button

**Use Link when:**
- Wrapping icons or images with links
- Creating navigation menu items
- Inline text links within content
- Clickable content that doesn't need button-like appearance

**Use Button when:**
- Creating call-to-action elements
- Prominent navigation that should look like a button
- Form submissions or actions
- Any element that needs button-like visual emphasis

## Component Structure

```
Link/
├── index.tsx                     # Main component
├── types.ts                      # TypeScript type definitions
├── ContentFields.tsx             # HubSpot field definitions
├── StyleFields.tsx               # HubSpot style field definitions
├── index.module.scss             # SCSS module with design tokens
└── stories/
    ├── Link.stories.tsx          # Storybook examples
    ├── LinkDecorator.tsx         # Storybook decorator
    └── LinkDecorator.module.css  # Decorator styles
```

## Props

The Link component supports **two mutually exclusive usage patterns**. You must use one approach or the other, but **NOT BOTH**.

### Pattern 1: Field-based (Recommended for HubSpot CMS)

Pass a `linkField` prop containing HubSpot link field data. The component automatically extracts href, target, and rel values.

```tsx
{
  linkField: {                                       // HubSpot link field value
    url?: { href?: string; type?: string };          // Link URL object
    open_in_new_tab?: boolean;                       // Open in new tab
    no_follow?: boolean;                             // Add nofollow rel
  };
  variant?: 'primary' | 'secondary' | 'tertiary';    // Visual style variant (default: 'primary')
  className?: string;                                // Additional CSS classes
  style?: React.CSSProperties;                       // Inline styles (including CSS variables)
  children?: React.ReactNode;                        // Link text/content
}
```

### Pattern 2: Manual (For Custom/Programmatic Usage)

Pass individual `href`, `target`, and `rel` props directly.

```tsx
{
  href: string;                                      // Link destination URL (required)
  target?: '_self' | '_blank' | '_parent' | '_top';  // Link target behavior
  rel?: string;                                      // Link relationship (e.g., 'noopener noreferrer')
  variant?: 'primary' | 'secondary' | 'tertiary';    // Visual style variant (default: 'primary')
  className?: string;                                // Additional CSS classes
  style?: React.CSSProperties;                       // Inline styles (including CSS variables)
  children?: React.ReactNode;                        // Link text/content
}
```

**TypeScript enforces this pattern** - you cannot use `linkField` together with `href`/`target`/`rel`.

## Usage Examples

### Pattern 1: Field-based (Recommended for HubSpot CMS)

#### Basic Field-based Link

```tsx
import Link from '@hubspot/cms-component-library/Link';

// In a HubSpot module:
export default function MyModule({ fieldValues }) {
  return (
    <Link linkField={fieldValues.link}>
      {fieldValues.linkText}
    </Link>
  );
}
```

#### Field-based Link with Variant

```tsx
<Link
  linkField={fieldValues.link}
  variant="secondary"
>
  Visit HubSpot
</Link>
```

#### Field-based Link with Style Override

```tsx
<Link
  linkField={fieldValues.link}
  style={{
    '--hscl-link-textDecoration': 'none',
    '--hscl-link-textDecoration-hover': 'underline',
  }}
>
  Visit HubSpot
</Link>
```

### Pattern 2: Manual (For Custom/Programmatic Usage)

#### Basic Manual Link

```tsx
import Link from '@hubspot/cms-component-library/Link';

<Link href="https://www.hubspot.com">
  Visit HubSpot
</Link>
```

#### External Link (New Tab)

```tsx
<Link
  href="https://www.hubspot.com"
  target="_blank"
>
  Open in New Tab
</Link>
```

#### Navigation Menu

```tsx
<nav>
  <Link href="/home">Home</Link>
  <Link href="/about">About</Link>
  <Link href="/contact">Contact</Link>
</nav>
```

### Using Variants

```tsx
<Link href="https://www.hubspot.com" variant="primary">
  Primary Link
</Link>

<Link href="https://www.hubspot.com" variant="secondary">
  Secondary Link
</Link>

<Link href="https://www.hubspot.com" variant="tertiary">
  Tertiary Link
</Link>
```

## HubSpot CMS Integration

### Field Definitions

The Link component provides field definitions for easy integration with HubSpot CMS modules.

#### ContentFields

```tsx
<Link.ContentFields
  linkLabel="Link URL"
  linkName="link"
  linkDefault={{
    url: {
      type: 'EXTERNAL',
      content_id: null,
      href: 'https://www.hubspot.com',
    },
  }}
/>
```

**Fields:**
- `link`: LinkField for href destination

#### StyleFields

```tsx
<Link.StyleFields
  variantLabel="Link style"
  variantName="linkVariant"
  variantDefault="primary"
/>
```

**Fields:**
- `linkVariant`: Choice field for variant selection (primary, secondary, tertiary)

### Module Usage Example

**Recommended (Field-based):**

```tsx
import Link from '@hubspot/cms-component-library/Link';

export default function NavigationModule({ fieldValues }) {
  return (
    <Link
      linkField={fieldValues.link}
      variant={fieldValues.linkVariant}
    >
      {fieldValues.linkText}
    </Link>
  );
}
```

**Manual (only when needed):**

```tsx
export default function NavigationModule({ fieldValues }) {
  return (
    <Link
      href="https://www.hubspot.com"
      target="_blank"
      rel="nofollow"
      variant="primary"
    >
      Go to HubSpot
    </Link>
  );
}
```

Note: The field-based approach is simpler and less error-prone.

## Styling

### Variants

The Link component supports three visual style variants through the `variant` prop:

- **primary** (default): Default link styling using `--hscl-link-color-primary` and `--hscl-link-color-hover-primary`
- **secondary**: Alternative styling using `--hscl-link-color-secondary` and `--hscl-link-color-hover-secondary`
- **tertiary**: Third alternative using `--hscl-link-color-tertiary` and `--hscl-link-color-hover-tertiary`

The component internally sets:
```tsx
style={{
  '--hscl-link-color': `var(--hscl-link-color-${variant})`,
  '--hscl-link-color-hover': `var(--hscl-link-color-hover-${variant})`,
}}
```

### CSS Variables

The Link component uses CSS variables for theming and customization:

**Base Styles:**
- `--hscl-link-display`: Display property (default: inline-block)
- `--hscl-link-color`: Text color (set by variant, no fallback)
- `--hscl-link-textDecoration`: Text decoration (default: underline)

**Hover States:**
- `--hscl-link-color-hover`: Hover text color (set by variant, no fallback)
- `--hscl-link-textDecoration-hover`: Hover text decoration (default: underline)

**Variant-specific Variables (must be defined globally):**
- `--hscl-link-color-primary`: Primary variant text color
- `--hscl-link-color-hover-primary`: Primary variant hover text color
- `--hscl-link-color-secondary`: Secondary variant text color
- `--hscl-link-color-hover-secondary`: Secondary variant hover text color
- `--hscl-link-color-tertiary`: Tertiary variant text color
- `--hscl-link-color-hover-tertiary`: Tertiary variant hover text color

### Custom Styling Examples

#### Override Text Decoration

```tsx
<Link
  href="https://www.hubspot.com"
  style={{
    '--hscl-link-textDecoration': 'none',
    '--hscl-link-textDecoration-hover': 'underline',
  }}
>
  Hover for underline
</Link>
```

#### Override Display

```tsx
<Link
  href="https://www.hubspot.com"
  style={{
    '--hscl-link-display': 'block',
  }}
>
  Block-level Link
</Link>
```

## Accessibility

The Link component follows accessibility best practices:

- **Semantic HTML**: Renders native `<a>` elements for proper browser behavior
- **Keyboard Navigation**: Full keyboard support via native link functionality
  - Enter key activates the link
  - Tab key moves focus to/from link
- **Link Security**:
  - Automatically uses `rel="noopener noreferrer"` with `target="_blank"` to prevent security vulnerabilities
  - Prevents new page from accessing `window.opener` object

## Best Practices

- **Use linkField prop when available**: If you have HubSpot field data, use the `linkField` prop instead of manually extracting href/target/rel
- **Do NOT mix approaches**: TypeScript will prevent you from using both `linkField` and `href` props together
- **Use variants for consistency**: Choose the appropriate variant (primary/secondary/tertiary) rather than overriding colors directly
- **Security**: The component automatically adds `rel="noopener noreferrer"` when target is `_blank`
- **CSS Variables**: Override design tokens using CSS variables for advanced customization
- **Minimal styling**: Keep link styling simple; use Button component for prominent CTAs

## Common Patterns

### Navigation Menu Item

```tsx
<Link href="/dashboard" variant="secondary">
  Dashboard
</Link>
```

### External Resource

```tsx
<Link
  href="https://developers.hubspot.com"
  target="_blank"
>
  API Documentation
</Link>
```

### Image Wrapper

```tsx
<Link href="/product">
  <img src="product.jpg" alt="Product name" />
</Link>
```

## Related Components

- **Button**: Use for prominent CTAs and elements that need button-like visual styling

### Link vs Button Decision Tree

```
Need to make something clickable?
│
├─ Should it look like a button (prominent, styled)?
│  └─ Use Button component (even if it links to a URL)
│
└─ Should it be a simple link (minimal styling)?
   └─ Use Link component
```
