# Icon Component

A wrapper around the HubSpot CMS Icon component that provides flexible sizing, customizable colors 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 customizable styling and accessibility options. It simplifies icon usage in HubSpot CMS projects by handling common configuration patterns like sizing, color theming through CSS variables, optional background containers, and proper accessibility attributes (SEMANTIC vs DECORATIVE purpose).

## 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 with design tokens
└── stories/
    ├── Icon.stories.tsx          # Component usage examples
    ├── IconDecorator.tsx         # Storybook decorator
    └── IconDecorator.module.css  # Decorator styles
```

## Components

### Icon (Main Component)

**Purpose:** Renders an icon with configurable size, color, background, and accessibility properties.

**Props:**
```tsx
{
  fieldPath?: string;                              // Path to icon in HubSpot fields
  size?: number | 'small' | 'medium' | 'large';   // Icon size — natural language or explicit px value. Omit to use CSS default (16px)
  fill?: string;                                   // Icon fill color (overrides CSS variable)
  className?: string;                              // Additional CSS classes
  style?: React.CSSProperties;                     // Inline styles (including CSS variables)
  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)
  showIconBackground?: boolean;                    // Renders a centered background div behind the icon (default: false)
  iconBackgroundColor?: string;                    // Background div color (used when showIconBackground is true)
  iconBackgroundPadding?: number;                  // Padding around the icon inside the background div in px (default: 12)
  iconBackgroundShape?: 'square' | 'rounded' | 'circle' | string; // Background shape — natural language or raw CSS border-radius value
}
```

## Usage Examples

### Basic Icon

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

<Icon
  fieldPath="icon"
  size={24}
/>
```

### Semantic Icon with Accessibility

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

### Icon with Custom Color

```tsx
<Icon
  fieldPath="icon"
  size={32}
  fill="#FF7A59"
/>
```

### Conditional Icon Display

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

### Icon with Background

```tsx
<Icon
  fieldPath="icon"
  size={24}
  showIconBackground={true}
  iconBackgroundColor="#2C2C2C"
  iconBackgroundPadding={16}
  iconBackgroundShape="circle"
/>
```

## 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: 'angle-right', unicode: 'f105', type: 'SOLID' }}
  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:**
- `iconColor`: ColorField for the icon fill color
- `iconBackgroundColor`: ColorField for the background div color
- `iconShape`: ChoiceField for the background border-radius (`'square'`, `'rounded'`, `'circle'`)
- `iconSize`: ChoiceField for icon size (`'small'` 16px, `'medium'` 24px, `'large'` 32px)

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"
      size={fieldValues.style?.iconSize}
      showIcon={fieldValues.showIcon}
      fill={fieldValues.style?.iconColor?.color}
      showIconBackground={fieldValues.style?.showIconBackground}
      iconBackgroundColor={fieldValues.style?.iconBackgroundColor?.color}
      iconBackgroundShape={fieldValues.style?.iconShape}
      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

### CSS Variables

The Icon component uses CSS variables for theming and customization:

**Base Styles:**
- `--hscl-icon-fill`: Icon fill color (default: `transparent`)
- `--hscl-icon-size`: Icon width and height (default: `16px`). Only set when `size` prop is provided — omitting `size` lets the CSS default apply.

**Background Styles (applied when `showIconBackground` is true):**
- `--hscl-iconBackground-backgroundColor`: Background div color
- `--hscl-iconBackground-padding`: Padding around the icon inside the background div (default: 12px)
- `--hscl-iconBackground-shape`: Border-radius of the background div (default: 0px)


## 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 CSS variables for theming**: Override `--hscl-icon-fill` for consistent color theming across your application
- **Use natural language sizes**: Pass `'small'` (16px), `'medium'` (24px), or `'large'` (32px) to `size`, or an explicit `number` in pixels. Omit `size` entirely to use the CSS default of `16px`.
- **Field path**: The `fieldPath` prop should match the field name defined in ContentFields
- **Background shape**: Pass `iconShape` field values (`'square'`, `'rounded'`, `'circle'`) directly to `iconBackgroundShape` — the component maps them to CSS values internally. Raw CSS border-radius strings are also accepted.
