@whydrf/nava-icon-angular 0.1.0 → 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +282 -0
  3. package/package.json +5 -5
package/LICENSE CHANGED
@@ -1,6 +1,6 @@
1
1
  MIT License
2
2
 
3
- Copyright (c) 2026 whydrf
3
+ Copyright (c) 2026 Whydrf
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
package/README.md ADDED
@@ -0,0 +1,282 @@
1
+ <p align="center">
2
+ <img src="https://raw.githubusercontent.com/whydrf/nava-icon/main/docs/public/favicon.svg" width="60" alt="Nava Icons">
3
+ </p>
4
+
5
+ <h1 align="center">@whydrf/nava-icon-angular</h1>
6
+
7
+ <p align="center">
8
+ 950+ beautiful, tree-shakeable SVG icons for Angular 17+.
9
+ </p>
10
+
11
+ <p align="center">
12
+ <a href="https://www.npmjs.com/package/@whydrf/nava-icon-angular"><img src="https://img.shields.io/npm/v/@whydrf/nava-icon-angular?style=flat-square&color=red" alt="npm version"></a>
13
+ <a href="https://github.com/whydrf/nava-icon/blob/main/LICENSE"><img src="https://img.shields.io/npm/l/@whydrf/nava-icon-angular?style=flat-square" alt="license"></a>
14
+ <a href="https://www.npmjs.com/package/@whydrf/nava-icon-angular"><img src="https://img.shields.io/npm/dm/@whydrf/nava-icon-angular?style=flat-square&color=red" alt="npm downloads"></a>
15
+ </p>
16
+
17
+ ---
18
+
19
+ ## What is this?
20
+
21
+ `@whydrf/nava-icon-angular` is the Angular binding for [Nava Icons](https://github.com/whydrf/nava-icon) — a collection of 950+ handcrafted SVG icons. Each icon is a standalone Angular component with `OnPush` change detection, full TypeScript support, tree shaking, and two visual variants (regular outlines and filled shapes).
22
+
23
+ Unlike icon fonts or SVG sprites, every icon here is a proper Angular component with `@Input()` decorators. You use it in your templates exactly like any other component — no modules, no providers, no configuration.
24
+
25
+ ## Installation
26
+
27
+ ```bash
28
+ npm install @whydrf/nava-icon-angular
29
+ ```
30
+
31
+ **Requirements:** Angular 17 or later. Works with both standalone components and NgModule-based architectures.
32
+
33
+ ## Getting Started
34
+
35
+ All icons are **standalone components** — you don't need to import them into an NgModule. Just import them directly into your component:
36
+
37
+ ```typescript
38
+ import { Component } from '@angular/core'
39
+ import { HomeIconComponent, SearchIconComponent, SettingsIconComponent } from '@whydrf/nava-icon-angular'
40
+
41
+ @Component({
42
+ selector: 'app-navigation',
43
+ standalone: true,
44
+ imports: [HomeIconComponent, SearchIconComponent, SettingsIconComponent],
45
+ template: `
46
+ <nav>
47
+ <home-icon [size]="24" />
48
+ <search-icon [size]="24" color="gray" />
49
+ <settings-icon [size]="24" />
50
+ </nav>
51
+ `,
52
+ })
53
+ export class NavigationComponent {}
54
+ ```
55
+
56
+ That's it — no `NavaIconsModule`, no global registration. The component's selector is the kebab-case version of the icon name (e.g., `HomeIconComponent` → `<home-icon>`).
57
+
58
+ ## How Tree Shaking Works
59
+
60
+ This is the most important concept to understand. When you write:
61
+
62
+ ```typescript
63
+ import { HomeIconComponent } from '@whydrf/nava-icon-angular'
64
+ ```
65
+
66
+ Your bundler (the Angular CLI uses esbuild under the hood) traces this import and includes **only** the `HomeIconComponent` in your production bundle. The other 949 icons are completely eliminated. This is why static imports are strongly recommended.
67
+
68
+ In contrast, this pattern imports everything:
69
+
70
+ ```typescript
71
+ // ❌ Don't do this in production — bundles all 950+ icons
72
+ import * as Icons from '@whydrf/nava-icon-angular'
73
+ ```
74
+
75
+ If you need to render icons dynamically (e.g., the icon name comes from an API or user input), use the `IconComponent` instead. It's designed for that specific use case.
76
+
77
+ ## Two Variants: Regular and Filled
78
+
79
+ Every icon ships in two visual styles:
80
+
81
+ - **Regular** — Stroke-based outlines. Clean, minimal, and ideal for most UI contexts like navigation, toolbars, and forms.
82
+ - **Filled** — Solid shapes with filled regions. Great for emphasis, active states, or when you want an icon to stand out.
83
+
84
+ You control which variant to show with the `mode` input:
85
+
86
+ ```typescript
87
+ import { Component } from '@angular/core'
88
+ import { CheckCircleIconComponent, HeartIconComponent } from '@whydrf/nava-icon-angular'
89
+
90
+ @Component({
91
+ selector: 'app-status',
92
+ standalone: true,
93
+ imports: [CheckCircleIconComponent, HeartIconComponent],
94
+ template: `
95
+ <!-- Show a filled heart when liked, outline when not -->
96
+ <heart-icon
97
+ [size]="24"
98
+ [mode]="isLiked ? 'filled' : 'regular'"
99
+ [color]="isLiked ? 'red' : 'gray'"
100
+ />
101
+
102
+ <!-- Always show filled for completed tasks -->
103
+ <check-circle-icon [size]="24" mode="filled" color="green" />
104
+ `,
105
+ })
106
+ export class StatusComponent {
107
+ isLiked = false
108
+ }
109
+ ```
110
+
111
+ The mode switching is instant — no re-fetching, no lazy loading. Both variants are bundled together.
112
+
113
+ ## The Dynamic `IconComponent`
114
+
115
+ Sometimes you can't use static imports. Maybe the icon name comes from an API, a database, or user configuration. For these cases, the package exports an `IconComponent`:
116
+
117
+ ```typescript
118
+ import { Component } from '@angular/core'
119
+ import { IconComponent } from '@whydrf/nava-icon-angular'
120
+
121
+ @Component({
122
+ selector: 'app-dynamic-icon',
123
+ standalone: true,
124
+ imports: [IconComponent],
125
+ template: `
126
+ <!-- The name input accepts kebab-case strings -->
127
+ <nava-icon [name]="iconName" [size]="24" />
128
+ <nava-icon name="check-circle" [size]="24" mode="filled" color="green" />
129
+ <nava-icon name="arrow-right" [size]="16" />
130
+ `,
131
+ })
132
+ export class DynamicIconComponent {
133
+ iconName = 'home'
134
+ }
135
+ ```
136
+
137
+ **Important:** The `IconComponent` imports all icons internally, so it cannot be tree-shaken. Your bundle will include all 950+ icons. Use it only when static imports aren't feasible.
138
+
139
+ ## Customizing Appearance
140
+
141
+ Since icons are standard SVG elements, you can customize them with CSS and standard Angular template bindings:
142
+
143
+ ```typescript
144
+ import { Component } from '@angular/core'
145
+ import { HomeIconComponent } from '@whydrf/nava-icon-angular'
146
+
147
+ @Component({
148
+ selector: 'app-custom-icon',
149
+ standalone: true,
150
+ imports: [HomeIconComponent],
151
+ template: `
152
+ <home-icon
153
+ [size]="32"
154
+ color="#6366f1"
155
+ [stroke-width]="1"
156
+ class="icon-hover"
157
+ [style]="{ transition: 'transform 0.2s', cursor: 'pointer' }"
158
+ (click)="navigate('/')"
159
+ />
160
+ `,
161
+ styles: [`
162
+ .icon-hover:hover {
163
+ transform: scale(1.1);
164
+ }
165
+ `],
166
+ })
167
+ export class CustomIconComponent {
168
+ navigate(path: string) {
169
+ // your navigation logic
170
+ }
171
+ }
172
+ ```
173
+
174
+ ### Colors
175
+
176
+ You can pass colors in any format the browser understands — hex codes, RGB, HSL, named colors, or CSS variables:
177
+
178
+ ```html
179
+ <home-icon color="#1a1a2e" /> <!-- Hex -->
180
+ <home-icon color="rgb(99, 102, 241)" /> <!-- RGB -->
181
+ <home-icon color="oklch(65% 0.27 264)" /> <!-- OKLCH -->
182
+ <home-icon color="var(--primary)" /> <!-- CSS variable -->
183
+ ```
184
+
185
+ With **Tailwind CSS**, the `color` input defaults to `currentColor`, so Tailwind's `text-*` utilities work directly:
186
+
187
+ ```html
188
+ <!-- Combine color, size, and hover effects -->
189
+ <home-icon class="text-emerald-400 w-8 h-8 hover:text-emerald-300 transition-colors" />
190
+
191
+ <!-- Dark mode support -->
192
+ <home-icon class="text-gray-900 dark:text-white" />
193
+ ```
194
+
195
+ ## Accessibility
196
+
197
+ Icons include built-in accessibility features:
198
+
199
+ - When you provide a `title` input, an invisible `<title>` element is added inside the SVG, which screen readers announce.
200
+ - Decorative icons (no `title`) are implicitly `aria-hidden` since SVGs without titles are ignored by assistive technology.
201
+
202
+ ```html
203
+ <!-- Meaningful icon — screen reader announces "Go to homepage" -->
204
+ <home-icon title="Go to homepage" />
205
+
206
+ <!-- Decorative icon — screen reader ignores it -->
207
+ <home-icon />
208
+ ```
209
+
210
+ ## Server-Side Rendering
211
+
212
+ Nava Icons works with Angular SSR and hydration out of the box. Icons are rendered as regular HTML/SNG elements — no client-side JavaScript required to display them.
213
+
214
+ ```typescript
215
+ import { Component } from '@angular/core'
216
+ import { HomeIconComponent } from '@whydrf/nava-icon-angular'
217
+
218
+ @Component({
219
+ imports: [HomeIconComponent],
220
+ template: `<home-icon [size]="24" />`,
221
+ })
222
+ export class ServerComponent {}
223
+ ```
224
+
225
+ ## OnPush Change Detection
226
+
227
+ All icon components use `ChangeDetectionStrategy.OnPush` by default. This means Angular only re-renders an icon when its input values actually change — not on every change detection cycle. This is the recommended strategy for performance-critical applications.
228
+
229
+ ## TypeScript
230
+
231
+ The package includes full TypeScript definitions. You get autocompletion for icon names and type checking for all inputs:
232
+
233
+ ```typescript
234
+ import type { IconName, IconMode } from '@whydrf/nava-icon-angular'
235
+
236
+ // IconName gives you autocompletion for all 950+ icon names
237
+ const icon: IconName = 'home' // ✅ valid
238
+ const bad: IconName = 'invalid' // ❌ compile error
239
+
240
+ // IconMode constrains to 'regular' | 'filled'
241
+ const mode: IconMode = 'filled' // ✅
242
+ ```
243
+
244
+ ## Inputs Reference
245
+
246
+ | Input | Type | Default | Description |
247
+ |-------|------|---------|-------------|
248
+ | `size` | `number \| string` | `24` | Width and height in pixels |
249
+ | `color` | `string` | `currentColor` | SVG stroke/fill color. `currentColor` inherits from parent CSS |
250
+ | `strokeWidth` | `number \| string` | `0.5` | Controls line thickness for stroke-based icons |
251
+ | `mode` | `"regular" \| "filled"` | `"regular"` | Toggles between outline and solid variants |
252
+ | `title` | `string` | — | Accessible title for screen readers |
253
+
254
+ All standard HTML attributes (`class`, `style`, `(click)`, `(mouseenter)`, `[attr.data-*]`, `[attr.aria-*]`, etc.) are also supported.
255
+
256
+ ## Popular Icons
257
+
258
+ | Category | Icons |
259
+ |----------|-------|
260
+ | **Arrows** | `arrow-back`, `arrow-right`, `arrow-from-left`, `arrow-to-top`, `refresh`, `redo`, `undo` |
261
+ | **Interface** | `home`, `search`, `settings`, `menu`, `check-circle`, `x-circle`, `copy`, `trash` |
262
+ | **Communication** | `bell`, `mail`, `phone`, `message-square`, `send`, `at` |
263
+ | **Files** | `file`, `folder`, `download`, `upload`, `archive`, `clipboard` |
264
+ | **Media** | `camera`, `image`, `music`, `video`, `play`, `pause` |
265
+ | **Objects** | `star`, `bookmark`, `lock`, `key`, `award`, `gift` |
266
+ | **Weather** | `sun`, `moon`, `cloud`, `droplet`, `wind`, `umbrella` |
267
+ | **Shopping** | `cart`, `credit-card`, `bag`, `tag`, `badge`, `diamond` |
268
+
269
+ Browse all 950+ icons with live preview at [**nava-icons.dev**](https://nava-icons.dev).
270
+
271
+ ## When to Use What
272
+
273
+ | Scenario | Use |
274
+ |----------|-----|
275
+ | Icon name is known at build time | Static import: `import { HomeIconComponent } from '...'` |
276
+ | Icon name comes from API/user input | Dynamic: `<nava-icon [name]="..." />` |
277
+ | Icon toggles between outline/filled | `mode` input: `<home-icon [mode]="..." />` |
278
+ | Icon needs click handler | `(click)` event: `<home-icon (click)="..." />` |
279
+
280
+ ## License
281
+
282
+ [MIT](https://github.com/whydrf/nava-icon/blob/main/LICENSE) &copy; [whydrf](https://github.com/whydrf)
package/package.json CHANGED
@@ -1,21 +1,21 @@
1
1
  {
2
2
  "name": "@whydrf/nava-icon-angular",
3
- "version": "0.1.0",
3
+ "version": "1.0.1",
4
4
  "type": "module",
5
5
  "sideEffects": false,
6
6
  "description": "Angular components for Nava Icons",
7
- "main": "./dist/index.mjs",
8
- "module": "./dist/index.mjs",
7
+ "main": "./dist/index.cjs",
8
+ "module": "./dist/index.js",
9
9
  "types": "./dist/index.d.ts",
10
10
  "exports": {
11
11
  ".": {
12
12
  "types": "./dist/index.d.ts",
13
- "import": "./dist/index.mjs",
13
+ "import": "./dist/index.js",
14
14
  "require": "./dist/index.cjs"
15
15
  },
16
16
  "./icons": {
17
17
  "types": "./dist/index.d.ts",
18
- "import": "./dist/index.mjs",
18
+ "import": "./dist/index.js",
19
19
  "require": "./dist/index.cjs"
20
20
  },
21
21
  "./package.json": "./package.json"