npm package: @semicons/react
Description: React component library for Semicons - semantic icon tokens with dual sprite/inline modes
Latest version: 0.0.1

# @semicons/react

React component library for Semicons - semantic icon tokens with dual sprite/inline modes.

## Features

- **Dual Mode Rendering**: Sprite (default) or inline SVG rendering
- **Tree-shakeable**: Only bundle what you use
- **A11y by default**: Proper ARIA attributes for screen readers
- **Type-safe**: Full TypeScript support

## Installation

```bash
pnpm add @semicons/react
```

## Quick Start

```tsx
import { Icon, SemiconsProvider } from '@semicons/react';

export function App() {
  return (
    <SemiconsProvider spriteUrl="/semicons.svg">
      <Icon name="navigation:menu" />
      <Icon name="action:edit" size="lg" />
      <Icon name="status:error" mode="inline" />
    </SemiconsProvider>
  );
}
```

## Modes

### Sprite Mode (Default)

Uses `<use href="#icon-name" />` to reference symbols from an external SVG sprite file.

```tsx
<Icon name="navigation:menu" mode="sprite" />
```

**Requirements:**
- Deploy `semicons.svg` to your public folder
- Default sprite URL: `/semicons.svg`
- Configure via `SemiconsProvider` or `spriteUrl` prop

### Inline Mode

Renders SVG directly inline. Useful for SSR, offline apps, or when sprite isn't available.

```tsx
<Icon name="navigation:menu" mode="inline" />
```

**Requirements:**
- CLI generates `src/icons.generated/inline.ts`
- Import and initialize at app start:

```tsx
// main.tsx
import { setInlineIcons, setIconMeta } from '@semicons/react';
import { INLINE_ICONS, ICON_META } from './icons.generated/inline';

setInlineIcons(INLINE_ICONS);
setIconMeta(ICON_META);
```

### Auto Mode (Recommended)

Automatically chooses sprite if available, falls back to inline.

```tsx
<Icon name="navigation:menu" mode="auto" /> // Default
```

## API

### Icon Props

| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `name` | `string` | Required | Icon token name (e.g., `navigation:menu`) |
| `mode` | `'auto' \| 'sprite' \| 'inline'` | `'auto'` | Render mode |
| `spriteUrl` | `string` | `/semicons.svg` | Sprite file URL |
| `size` | `number \| 'xs' \| 'sm' \| 'md' \| 'lg' \| 'xl'` | `'md'` | Icon size (12/16/20/24/32px) |
| `decorative` | `boolean` | `true` | If true, icon is decorative |
| `ariaLabel` | `string` | - | Accessible label (required if decorative=false) |
| `title` | `string` | - | `<title>` element content |

### SemiconsProvider

Provides default values for all Icon components.

```tsx
interface SemiconsProviderProps {
  spriteUrl?: string;        // Default: '/semicons.svg'
  defaultMode?: IconMode;    // Default: 'auto'
  defaultSize?: IconSize;
  defaultDecorative?: boolean; // Default: true
}
```

### Helper Functions

```tsx
getIconMeta(name)    // Get icon metadata
isDeprecated(name)   // Check if icon is deprecated
```

## Accessibility Best Practices

### Decorative Icons

Icons that add visual context (not conveying information) should be decorative:

```tsx
<button aria-label="Open menu">
  <Icon name="navigation:menu" decorative />
</button>
```

- Renders `aria-hidden="true"`
- No screen reader announcement

### Informative Icons

Icons that convey meaning must have an accessible label:

```tsx
<Icon 
  name="status:error" 
  decorative={false} 
  ariaLabel="Error: Form validation failed"
/>
```

- Renders `role="img"` with `aria-label`
- Screen reader announces the label

## Setup with Generated Icons

### 1. Configure CLI

Add to your `semicons.config.ts`:

```ts
export default defineConfig({
  generate: {
    inline: true,
    output: './src/icons.generated',
  },
});
```

### 2. Initialize in App

```tsx
// main.tsx
import { setInlineIcons, setIconMeta } from '@semicons/react';
import { INLINE_ICONS, ICON_META } from './icons.generated/inline';

setInlineIcons(INLINE_ICONS);
setIconMeta(ICON_META);

render(<App />, document.getElementById('root'));
```

## Tree Shaking

The runtime package doesn't include any icon data. Generated files should be:

- Split by category (optional, configured in CLI)
- Imported and registered via `setInlineIcons()`/`setIconMeta()`

This ensures only used icons are bundled.

## License

MIT