# Icon Component

A wrapper around the HubSpot CMS Icon component that provides flexible sizing, theme-driven styling via CSS variables, and accessibility options.

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

## Purpose

The Icon component wraps the native HubSpot CMS Icon component to provide a consistent interface for rendering icons with theme-driven styling and accessibility options. Styling (color, background, border) is controlled by CSS variables injected by the HubSpot theme system based on the selected icon variant. The `data-icon-variant` attribute on the wrapper element is what scopes those CSS variables.

## Component Structure

```
Icon/
├── index.tsx                     # Main component with render logic
├── types.ts                      # TypeScript type definitions
├── ContentFields.tsx             # HubSpot field definitions for icon content
├── StyleFields.tsx               # HubSpot field definitions for icon styles
├── index.module.scss             # CSS module consuming theme CSS variables
└── stories/
    ├── Icon.stories.tsx          # Component usage examples
    ├── IconDecorator.tsx         # Storybook decorator
    └── IconDecorator.module.scss # Decorator styles
```

## Components

### Icon (Main Component)

**Purpose:** Renders an icon with configurable size, variant-based theme styling, and accessibility properties.

**Props:**
```tsx
{
  fieldPath?: string;                              // Path to icon in HubSpot fields
  variant?: string;                                // Icon variant name, sets data-icon-variant for CSS var scoping. Omit to allow parent CSS variables to cascade.
  size?: 'small' | 'medium' | 'large';             // Icon size (small=16px, medium=24px, large=32px). Omit to use CSS default (16px)
  className?: string;                              // Additional CSS classes
  style?: React.CSSProperties;                     // Inline styles (merged with size styles)
  showIcon?: boolean;                              // Toggle icon visibility (default: true)
  purpose?: 'SEMANTIC' | 'DECORATIVE';            // Icon accessibility role (default: 'DECORATIVE')
  title?: string;                                  // Icon title for screen readers (use with SEMANTIC)
}
```

## CSS Variables

Styling is driven by the following CSS variables, injected by the theme system and scoped via `data-icon-variant`:

| Variable | Property | Fallback |
|---|---|---|
| `--hs-icon-color` | SVG fill | `currentColor` |
| `--hs-icon-backgroundColor` | Background color | `transparent` |
| `--hs-icon-borderRadius` | Border radius | `0` |
| `--hs-icon-borderStyle` | Border style | `solid` |
| `--hs-icon-borderTopWidth` | Top border width | `0` |
| `--hs-icon-borderRightWidth` | Right border width | `0` |
| `--hs-icon-borderBottomWidth` | Bottom border width | `0` |
| `--hs-icon-borderLeftWidth` | Left border width | `0` |
| `--hs-icon-borderColor` | Border color | `transparent` |

## Usage Examples

### Basic Icon

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

<Icon
  fieldPath="icon"
  size="medium"
/>
```

### Icon with Variant

```tsx
<Icon
  fieldPath="icon"
  size="medium"
  variant="icon2"
/>
```

### Semantic Icon with Accessibility

```tsx
<Icon
  fieldPath="icon"
  size="medium"
  purpose="SEMANTIC"
  title="Download file"
/>
```

### Conditional Icon Display

```tsx
<Icon
  fieldPath="icon"
  size="small"
  showIcon={shouldShowIcon}
/>
```

## HubSpot CMS Integration

### Field Definitions

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

#### ContentFields

Configurable props for icon selection and visibility:

```tsx
<Icon.ContentFields
  iconLabel="Icon"
  iconName="icon"
  iconDefault={{ name: 'check-circle', unicode: 'f058', type: 'REGULAR' }}
  addIconToggle={true}
  showIconLabel="Show icon"
  showIconName="showIcon"
  showIconDefault={false}
/>
```

**Fields:**
- `icon`: IconField for selecting the icon
- `showIcon`: BooleanField toggle for icon visibility (optional, enabled with `addIconToggle={true}`)

#### StyleFields

Configurable props for icon appearance:

```tsx
<Icon.StyleFields />
```

**Fields:**
- `iconVariant`: VariantSelectionField for choosing the icon theme variant (controls color, background, border via CSS vars)
- `iconSize`: ChoiceField for icon size — `small`, `medium`, `large`; displayed as pill buttons

All fields support `label`, `name`, and `default` customization props, and can be hidden via `hideFields`.

### Module Usage Example

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

export default function IconModule({ fieldValues }) {
  return (
    <Icon
      fieldPath="icon"
      variant={fieldValues.style?.iconVariant?.variant_name}
      size={fieldValues.style?.iconSize}
      showIcon={fieldValues.showIcon}
      purpose="DECORATIVE"
    />
  );
}
```

### Module Fields Example

```tsx
import { ModuleFields, FieldGroup } from '@hubspot/cms-components/fields';
import Icon from '@hubspot/cms-component-library/Icon';

export const fields = (
  <ModuleFields>
    <Icon.ContentFields addIconToggle={true} />
    <FieldGroup name="style" label="Style" tab="STYLE">
      <Icon.StyleFields />
    </FieldGroup>
  </ModuleFields>
);
```

## Styling

When `showIconBackground` is true, the Icon component renders a `<div data-icon-variant={variant}>` wrapper that the HubSpot theme system uses to scope CSS variables. The `data-icon-variant` attribute is only present when `variant` is explicitly provided — omitting it allows CSS variables from a parent element (e.g. a card's `data-card-variant`) to cascade through unimpeded. All color, background, and border properties come from the theme — no inline styles are used for these.

The only inline styles applied are width and height when the `size` prop is provided.

## Accessibility

The Icon component follows accessibility best practices:

- **Icon Purpose**:
  - `DECORATIVE` (default): Icon is purely visual, hidden from screen readers with `aria-hidden`
  - `SEMANTIC`: Icon conveys meaning, includes accessible title for screen readers
- **Title Attribute**: Use `title` prop with `purpose="SEMANTIC"` to provide screen reader description
- **Conditional Rendering**: The `showIcon` prop allows dynamic icon visibility without affecting layout

## Best Practices

- **Choose the right purpose**: Use `SEMANTIC` when the icon conveys important meaning, `DECORATIVE` when it's purely visual
- **Always provide title with SEMANTIC**: When using `purpose="SEMANTIC"`, always include a meaningful `title` for screen readers
- **Use named sizes**: Pass `'small'` (16px), `'medium'` (24px), or `'large'` (32px) to `size`. Omit `size` entirely to use the CSS default of `16px`
- **Field path**: The `fieldPath` prop should match the field name defined in ContentFields
- **Variant drives all visual styling**: Do not use inline styles for color or background — configure those through the theme variant system
