npm package: @heartpace/icons
Description: SVG icon library with recursive autogeneration
Author: Heartpace
Latest version: 0.1.12

# Heartpace Icons

A TypeScript/React icon library with recursive SVG autogeneration. Automatically converts SVG files from nested folders into unique React components using SVGR and tsup.

## Features

- 🔄 **Recursive SVG Processing**: Automatically scans nested folders in `src/icons`
- 🎯 **Unique Component Names**: Generates globally unique component names based on folder structure
- 📁 **Nested Folder Support**: Organize your icons in any folder structure you want
- 🔀 **Duplicate File Name Handling**: SVG files can have the same name in different folders
- ⚡ **TypeScript Support**: Full TypeScript definitions included
- 📦 **Tree-shakeable**: Built with tsup for optimal bundle size
- 🎨 **SVGR Integration**: Uses SVGR to convert SVGs to optimized React components

## Installation

```bash
npm install
```

## Usage

### Adding Icons

Place your SVG files in the `src/icons` directory. You can organize them in any nested folder structure:

```
src/icons/
  ├── icon.svg
  ├── ui/
  │   ├── button/
  │   │   └── icon.svg
  │   └── icon.svg
  └── actions/
      ├── icon.svg
      └── save.svg
```

### Generating Components

Run the generation script to convert SVGs to React components:

```bash
npm run generate
```

This will:
1. Recursively scan `src/icons` for all SVG files
2. Generate unique component names based on folder structure
3. Convert SVGs to React components using SVGR
4. Create TypeScript component files in `src/generated/`
5. Update `src/index.ts` with all exports

### Building

Build the library for production:

```bash
npm run build
```

This runs the generation step and then builds with tsup, outputting:
- CommonJS: `dist/index.js`
- ES Modules: `dist/index.mjs`
- TypeScript definitions: `dist/index.d.ts`

### Development

Watch mode for development:

```bash
npm run dev
```

## Component Naming

Component names are automatically generated from the folder structure and file name:

- **Path**: `src/icons/ui/button/icon.svg` → **Component**: `UiButtonIcon`
- **Path**: `src/icons/actions/save.svg` → **Component**: `ActionsSave`
- **Path**: `src/icons/icon.svg` → **Component**: `Icon`

### Naming Rules

1. Each folder and file name is converted to PascalCase
2. All parts are joined together (no separators)
3. The `.svg` extension is removed
4. If duplicate names would occur, numbers are appended (e.g., `Icon2`, `Icon3`)

### Examples

| File Path | Component Name |
|-----------|----------------|
| `icon.svg` | `Icon` |
| `ui/icon.svg` | `UiIcon` |
| `ui/button/icon.svg` | `UiButtonIcon` |
| `actions/save.svg` | `ActionsSave` |
| `arrows/icon/arrow/swap.svg` | `ArrowsIconArrowSwap` |

## Using the Icons

After building, import icons from the package:

```tsx
import { ArrowsIconsArrowArrow2, GeneralIconlyLightHome, FlagsUsa } from '@heartpace/icons';

function MyComponent() {
  return (
    <div>
      {/* Default size (24x24) with custom stroke color */}
      <ArrowsIconsArrowArrow2 stroke="#00A0E5" />
      
      {/* Custom size with custom stroke color */}
      <ArrowsIconsArrowArrow2 width={100} height={100} stroke="#00A0E5" />
      
      {/* Using CSS color via className */}
      <GeneralIconlyLightHome className="w-6 h-6 text-blue-500" stroke="currentColor" />
      
      {/* Flags keep their original colors */}
      <FlagsUsa width={32} height={32} />
    </div>
  );
}
```

### Color Control

All icons (except flags) use `currentColor` for `stroke` and `fill` attributes, which means:

- **Pass `stroke` or `fill` props** to set specific colors: `<Icon stroke="#00A0E5" />`
- **Use CSS `color` property** via `className`: `<Icon className="text-blue-500" stroke="currentColor" />`
- **Flags preserve their original colors** and cannot be recolored

All icons accept standard React SVG props (`className`, `width`, `height`, `fill`, `stroke`, etc.).

## Categories

The library automatically generates a `categories.json` file that groups all icons by their root category (the first folder in the path). This file is available in the `dist` folder and can be imported for programmatic access to icons by category.

### Accessing Categories

```tsx
// Import categories JSON
import categories from '@heartpace/icons/categories';
// or
import categories from '@heartpace/icons/categories.json';

// Access icons by category
const arrowsIcons = categories.Arrows;
const flagsIcons = categories.Flags;
const generalIcons = categories.General;

// Each icon has:
// - componentName: The React component name
// - relativePath: Path from icons directory
// - fileName: The SVG file name

console.log(arrowsIcons[0]);
// {
//   componentName: "ArrowsIconArrowCloseMenu",
//   relativePath: "Arrows/Icon/Arrow/Close menu.svg",
//   fileName: "Close menu.svg"
// }
```

### TypeScript Support

TypeScript types are included for the categories:

```tsx
import type { Categories, IconInfo } from '@heartpace/icons/categories';

const categories: Categories = require('@heartpace/icons/categories.json');

// IconInfo type
interface IconInfo {
  componentName: string;
  relativePath: string;
  fileName: string;
}
```

## Tree-shaking Support

This library is fully optimized for tree-shaking! Only the icons you import will be included in your final bundle.

### ✅ Best Practices

```tsx
// ✅ GOOD: Named imports (tree-shakeable)
import { ArrowsIconArrowUp, FlagsFrance } from 'heartpace-icons';

// ❌ BAD: Namespace import (imports everything)
import * as Icons from 'heartpace-icons';
```

### 📊 Bundle Size Impact

- **Total library size**: ~240 KB (all 225 icons)
- **Single icon**: ~1-2 KB
- **With tree-shaking**: Only imported icons are bundled

Example: Importing 5 icons = ~5-10 KB instead of 240 KB! 🎉

For more details, see [TREE_SHAKING.md](./TREE_SHAKING.md).

## Project Structure

```
heartpace-icons/
├── src/
│   ├── icons/              # Place your SVG files here (any nested structure)
│   ├── generated/         # Auto-generated React components (gitignored)
│   └── index.ts           # Auto-generated exports (gitignored)
├── dist/                   # Build output (gitignored)
├── scripts/
│   └── generate.js        # SVG to React component generator
├── package.json
├── tsconfig.json
├── tsup.config.ts
└── README.md
```

## Scripts

- `npm run generate` - Generate React components from SVG files
- `npm run build` - Generate components and build the library
- `npm run dev` - Generate components and watch for changes

## How It Works

1. **Discovery**: The generator recursively scans `src/icons` for all `.svg` files
2. **Naming**: Component names are generated from the full folder path + filename
3. **Conversion**: Each SVG is converted to a React component using SVGR
4. **Generation**: TypeScript component files are created in `src/generated/`
5. **Export**: All components are exported from `src/index.ts`
6. **Build**: tsup bundles everything into distributable formats

## Requirements

- Node.js 18+
- React 18+ (peer dependency)

## License

MIT