npm package: @reliability-design/icons
Description: SVG icon library for the Reliability Design System — Lit web component + tree-shakable exports
Author: Reliability Design System
Latest version: 1.1.0

# @reliability-design/icons

SVG icon library for the Reliability Design System.

Provides a Lit-based `<rel-icon>` web component, a runtime icon dictionary, TypeScript types, and tree-shakable per-icon imports — shared by **both web and Angular** consumers.

---

## Architecture overview

```text
raw-svg/                     ← Source of truth: raw SVG exports from Figma
  arrow-left.svg
  check.svg
  ...

scripts/
  fetch-figma-icons.ts       ← Downloads SVGs from Figma API  ⚠️ BLOCKED: needs PAT
  normalize-icons.ts         ← Optimizes SVGs via SVGO, converts colors to currentColor
  validate-icons.ts          ← Validates filenames, viewBox, duplicates — CI gate
  generate-icons.ts          ← Generates src/generated/** from raw-svg/

src/
  generated/                 ← AUTO-GENERATED. Do not hand-edit.
    svgs/
      arrow-left.ts          ← export const arrowLeft = '<svg ...>';
      ...
    icon-dictionary.ts       ← Runtime Record<IconName, string> for <rel-icon>
    icon-names.ts            ← TypeScript union type + array of all names
    index.ts                 ← Barrel

  rel-icon.ts                ← <rel-icon> Lit web component
  index.ts                   ← Public API barrel

  svgs/                      ← LEGACY: hand-authored Lit SVGTemplateResult exports
  icon-dictionary.ts         ← LEGACY: RelIcons dictionary (snake_case keys)
```

---

## Pipeline steps

| Step | Script | Description |
| ---- | ------ | ----------- |
| 1. Fetch | `npm run icons:fetch` | Download raw SVGs from Figma into `raw-svg/` |
| 2. Normalize | `npm run icons:normalize` | SVGO optimise, strip dimensions, convert to `currentColor` |
| 3. Validate | `npm run icons:validate` | Check filenames, viewBox, duplicates (CI gate) |
| 4. Generate | `npm run icons:generate` | Emit `src/generated/**` TypeScript modules |
| 5. Build | `npm run build` | Compile TypeScript → `dist/` |

Run steps 2–4 together:

```sh
npm run icons:build-assets   # normalize + validate + generate
npm run build
```

---

## ⚠️ Current status

| Step | Status |
| ---- | ------ |
| Package structure & scripts | ✅ Complete |
| `<rel-icon>` web component | ✅ Complete (renders from generated dictionary) |
| SVGO config | ✅ Complete |
| `icons:fetch` script | ✅ Scaffolded — blocked on Figma PAT |
| `icons:normalize` script | ✅ Scaffolded — runs once SVGs exist |
| `icons:validate` script | ✅ Scaffolded — runs once SVGs exist |
| `icons:generate` script | ✅ Scaffolded — runs once SVGs exist |
| Generated icons in `src/generated/` | ⚠️ Empty placeholder — pipeline not yet run |
| Legacy icons in `src/svgs/` | ✅ 201 hand-authored Lit templates (backward compat) |

**The `<rel-icon>` component will not render icons** until the pipeline runs and
populates `src/generated/`. The legacy `RelIcons` dictionary (from the
pre-pipeline era) is still available for backward compatibility.

---

## Getting started (once PAT is available)

1. Copy `.env.example` to `.env` and fill in `FIGMA_TOKEN`:

   ```sh
   cp .env.example .env
   # Edit .env and add your Figma PAT
   ```

2. Run the full pipeline:

   ```sh
   npm run icons:fetch           # Download raw SVGs from Figma
   npm run icons:build-assets    # normalize → validate → generate
   npm run build                 # Compile TypeScript
   ```

---

## Naming conventions

| Context | Convention | Example |
| ------- | ---------- | ------- |
| SVG filename in `raw-svg/` | kebab-case | `arrow-left.svg` |
| Generated TS module | kebab-case | `src/generated/svgs/arrow-left.ts` |
| Export constant name | camelCase | `arrowLeft` |
| Runtime dictionary key | kebab-case | `'arrow-left'` |
| `<rel-icon name="">` attribute | kebab-case | `name="arrow-left"` |
| Legacy `RelIcons` key (old) | snake_case | `"arrow_left"` ← do not use in new code |

---

## Consuming the icons

### Web (Lit / vanilla HTML)

```ts
// Auto-registers <rel-icon> custom element
import '@reliability-design/icons/rel-icon';
```

```html
<!-- Decorative -->
<rel-icon name="arrow-left"></rel-icon>

<!-- Accessible (labelled) -->
<rel-icon name="warning" aria-label="Warning: action required"></rel-icon>

<!-- Named size preset: xs | sm | md (default) | lg | xl -->
<rel-icon name="check" size="lg"></rel-icon>

<!-- Custom size via CSS custom property -->
<rel-icon name="check" style="--rel-icon-size: 2rem;"></rel-icon>
```

#### Semantic tones

Use `tone` to apply a design-system color token without hardcoding a color value.

```html
<rel-icon name="check"        tone="success"></rel-icon>
<rel-icon name="alert-circle" tone="warning"></rel-icon>
<rel-icon name="close"        tone="danger"></rel-icon>
<rel-icon name="lock"         tone="disabled"></rel-icon>
```

| Tone | Token | Color |
| ---- | ----- | ----- |
| `success`  | `--rel-icon-success`  | green  |
| `warning`  | `--rel-icon-warning`  | orange |
| `danger`   | `--rel-icon-error`    | red    |
| `disabled` | `--rel-text-disabled` | grey   |
| `default`  | _(none — inherits `currentColor` from parent)_ | |

#### Direct color override

Use `color` for arbitrary colors. It accepts any valid CSS color value and takes precedence over `tone`.

```html
<!-- Hex -->
<rel-icon name="check" color="#ffffff"></rel-icon>

<!-- RGB / HSL -->
<rel-icon name="check" color="rgb(255 255 255)"></rel-icon>
<rel-icon name="check" color="hsl(0 0% 100%)"></rel-icon>

<!-- CSS variable / design token -->
<rel-icon name="check" color="var(--rel-color-text-primary)"></rel-icon>
```

#### Color precedence

```
color prop  >  tone prop  >  inherited currentColor from parent
```

You can also set `--rel-icon-color` directly via CSS if neither prop is set:

```css
.my-context rel-icon {
  --rel-icon-color: hotpink;
}
```

### Angular

Angular supports standard custom elements. Register the `CUSTOM_ELEMENTS_SCHEMA`
in your module or standalone component, then import the side-effect:

```ts
// app.module.ts (or standalone component)
import '@reliability-design/icons/rel-icon';

@NgModule({
  schemas: [CUSTOM_ELEMENTS_SCHEMA],
  // ...
})
export class AppModule {}
```

```html
<rel-icon name="check" size="lg"></rel-icon>
```

> **There is no separate Angular icon package.** Angular uses the same
> `<rel-icon>` web component as every other framework. Do not create a
> duplicate Angular-only icon registry.

### Direct SVG string imports (tree-shaking)

Once the pipeline has run:

```ts
import { arrowLeft } from '@reliability-design/icons/svgs/arrow-left';
// arrowLeft is a plain SVG string: '<svg viewBox="...">...</svg>'
```

### Icon dictionary (runtime lookup)

```ts
import { iconDictionary, type IconName } from '@reliability-design/icons/icon-dictionary';

const svg = iconDictionary['arrow-left']; // string | undefined
```

### Icon names (type-safe)

```ts
import { type IconName, iconNames } from '@reliability-design/icons/icon-names';

const name: IconName = 'arrow-left'; // TypeScript autocomplete
```

---

## Legacy API (pre-pipeline)

The following exports are maintained for backward compatibility. They use Lit's
`svg` tagged template result type and **snake_case** keys. Do not use them in
new code — they will be deprecated once the pipeline is fully operational.

```ts
import { RelIcons } from '@reliability-design/icons';
// RelIcons['cancel_circle']  ← SVGTemplateResult (Lit template)

import { iconArrowLeft } from '@reliability-design/icons';
// iconArrowLeft  ← SVGTemplateResult (Lit template)
```

---

## Do not hand-edit generated files

All files under `src/generated/` are overwritten by `npm run icons:generate`.
Changes made there will be lost on the next pipeline run.

To change an icon: update the source in Figma, re-fetch, and re-run the pipeline.

---

## Figma source

| Setting | Value |
| ------- | ----- |
| File key | `OY0XOJmHerGLseiaJV6jHY` |
| Icons root node ID | `53:175778` |
| PAT env var | `FIGMA_TOKEN` (see `.env.example`) |