# Shadow Utility Field

A standalone, reusable field definition that adds a consistent drop shadow control to any HubSpot CMS module. Part of the `utilityFields` category — not a UI component, but a composable field + CSS utility pair that can be attached to any element.

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

## Purpose

The Shadow utility field provides a consistent editor experience for drop shadow depth across modules and elements. It exposes a four-choice field (`none`, `subtle`, `medium`, `bold`) along with a CSS utility function (`getShadowClass`) that maps the field value to a co-located CSS module class. Use it when you want to give editors control over shadow depth without each module independently defining its own shadow values.

For non-rectangular elements (e.g. SVG-based shapes), use only the field for consistent UI and implement the CSS yourself using `filter: drop-shadow()`.

## Structure

```
utilityFields/Shadow/
├── StyleFields.tsx       # ChoiceField definition (none/subtle/medium/bold)
├── index.module.css      # Co-located box-shadow CSS classes
├── index.ts              # Exports { StyleFields, getShadowClass }
└── types.ts              # ShadowDepth type and StyleFieldsProps
```

## StyleFields

Adds a `Shadow` button-group choice field to the module editor.

**Configurable props:**
```tsx
<Shadow.StyleFields
  shadowLabel="Shadow"         // Field label (default: 'Shadow')
  shadowName="shadow"          // Field name in HubSpot data (default: 'shadow')
  shadowDefault="none"         // Default value (default: 'none')
  shadowAgentContext="..."     // AI context string
/>
```

**Field choices:** `none` | `subtle` | `medium` | `bold`

## getShadowClass

Maps a `ShadowDepth` value to the corresponding CSS module class from `index.module.css`. Returns `undefined` for `'none'` (no class applied).

```tsx
Shadow.getShadowClass('none')    // undefined
Shadow.getShadowClass('subtle')  // styles.shadowSubtle → box-shadow: 0px 2px 8px rgba(0,0,0,0.08)
Shadow.getShadowClass('medium')  // styles.shadowMedium → box-shadow: 0px 4px 16px rgba(0,0,0,0.12)
Shadow.getShadowClass('bold')    // styles.shadowBold   → box-shadow: 0px 8px 32px rgba(0,0,0,0.18)
```

## Shadow Values Reference

| Depth  | box-shadow                              |
|--------|-----------------------------------------|
| subtle | `0px 2px 8px rgba(0, 0, 0, 0.08)`      |
| medium | `0px 4px 16px rgba(0, 0, 0, 0.12)`     |
| bold   | `0px 8px 32px rgba(0, 0, 0, 0.18)`     |

## Usage Examples

### Full usage: field + CSS utility (most common)

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

export const fields = (
  <ModuleFields>
    <FieldGroup label="Style" name="style" tab="STYLE">
      <Shadow.StyleFields />
    </FieldGroup>
  </ModuleFields>
);
```

```tsx
// index.tsx
import Shadow from '@hubspot/cms-component-library/utilityFields/Shadow';
import { ShadowDepth } from '@hubspot/cms-component-library/utilityFields/Shadow/types';
import cx from '@hubspot/cms-component-library/utils/classname';

type Props = {
  style: { shadow: ShadowDepth };
};

export const Component = ({ style: { shadow } }: Props) => (
  <div className={cx(styles.wrapper, Shadow.getShadowClass(shadow))}>
    {/* content */}
  </div>
);
```

### Field-only usage (for SVG/non-rectangular elements)

Use `Shadow.StyleFields` for consistent field UI, but apply the shadow yourself via `filter`:

```tsx
// fields.tsx — same as above

// index.tsx
const SHADOW_FILTER = {
  subtle: 'drop-shadow(0px 2px 8px rgba(0, 0, 0, 0.08))',
  medium: 'drop-shadow(0px 4px 16px rgba(0, 0, 0, 0.12))',
  bold:   'drop-shadow(0px 8px 32px rgba(0, 0, 0, 0.18))',
};

const filter = shadow !== 'none' ? SHADOW_FILTER[shadow] : undefined;

<div style={{ ...(filter && { filter }) }}>
  <svg>...</svg>
</div>
```

### Custom field name (when shadow is nested in a field group)

```tsx
<Shadow.StyleFields shadowName="cardShadow" />

// Props type reflects the custom name
type Props = {
  style: { cardShadow: ShadowDepth };
};
```

## When to use utilityFields vs component StyleFields

- **Use `utilityFields/Shadow`** when shadow depth is an opt-in concern for the module author — it's not intrinsic to any one component and should apply to the module's primary element.
- **Do not** add shadow directly to a component's `StyleFields` — shadow is an element-level concern, not a component-level one. A `Card` component shouldn't own the shadow; the module composing the card decides whether to attach shadow.
