@icon-craft/react-ts 1.0.0
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.
- package/LICENSE +73 -0
- package/README.md +1018 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.esm.js +2 -0
- package/dist/index.esm.js.map +1 -0
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -0
- package/package.json +101 -0
package/README.md
ADDED
|
@@ -0,0 +1,1018 @@
|
|
|
1
|
+
# @icon-craft/react-ts
|
|
2
|
+
|
|
3
|
+
<div align="center">
|
|
4
|
+
|
|
5
|
+

|
|
6
|
+
|
|
7
|
+
**A comprehensive TypeScript-first React icon library with 3475+ beautifully crafted SVG icons**
|
|
8
|
+
|
|
9
|
+
[](https://www.npmjs.com/package/@icon-craft/react-ts)
|
|
10
|
+
[](https://www.npmjs.com/package/@icon-craft/react-ts)
|
|
11
|
+
[](https://bundlephobia.com/package/@icon-craft/react-ts)
|
|
12
|
+
[](https://github.com/PATEL-KRISH-0/icon-craft/blob/main/LICENSE)
|
|
13
|
+
[](https://www.typescriptlang.org/)
|
|
14
|
+
|
|
15
|
+
**3475+ icons** · **Full TypeScript support** · **Type-safe** · **IntelliSense autocomplete** · **Tree-shakeable** · **Zero dependencies**
|
|
16
|
+
|
|
17
|
+
[Installation](#-installation) · [Quick Start](#-quick-start) · [TypeScript Features](#-typescript-features) · [Documentation](#-documentation) · [Examples](#-examples)
|
|
18
|
+
|
|
19
|
+
</div>
|
|
20
|
+
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
## ✨ Features
|
|
24
|
+
|
|
25
|
+
- 🎨 **3475+ Premium Icons** - Unified collection from Feather Icons and Remix Icon
|
|
26
|
+
- 📘 **TypeScript First** - Built with TypeScript, includes complete type definitions
|
|
27
|
+
- 🔒 **Type-Safe** - Catch errors at compile time, not runtime
|
|
28
|
+
- 💡 **IntelliSense Support** - Full autocomplete for icon names and props in VS Code
|
|
29
|
+
- ⚛️ **Pure React Components** - Native TSX/JSX components with proper types
|
|
30
|
+
- 🎯 **Dual Usage Patterns** - Dynamic `<Icon name="..."/>` or direct `<IconHome/>`
|
|
31
|
+
- 🎨 **Fully Customizable** - Control size, color, stroke width, className, and more
|
|
32
|
+
- 📦 **Tree-Shakeable** - Only bundle the icons you actually use
|
|
33
|
+
- 🚀 **Zero Dependencies** - Only requires React as peer dependency (23MB source, ~2-5KB per icon when bundled)
|
|
34
|
+
- ♿ **Accessible** - Semantic SVG elements with proper ARIA support
|
|
35
|
+
- 🔧 **Framework Agnostic** - Works with Next.js, Vite, Create React App, Remix, etc.
|
|
36
|
+
- 🌳 **Production Ready** - Battle-tested, optimized, and maintained
|
|
37
|
+
|
|
38
|
+
---
|
|
39
|
+
|
|
40
|
+
## 📦 Installation
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
# NPM
|
|
44
|
+
npm install @icon-craft/react-ts
|
|
45
|
+
|
|
46
|
+
# Yarn
|
|
47
|
+
yarn add @icon-craft/react-ts
|
|
48
|
+
|
|
49
|
+
# PNPM
|
|
50
|
+
pnpm add @icon-craft/react-ts
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
**Peer Dependencies:**
|
|
54
|
+
- React >= 16.8.0
|
|
55
|
+
- React-DOM >= 16.8.0
|
|
56
|
+
|
|
57
|
+
**Recommended for TypeScript projects. For JavaScript-only projects, use [@icon-craft/react](https://www.npmjs.com/package/@icon-craft/react).**
|
|
58
|
+
|
|
59
|
+
---
|
|
60
|
+
|
|
61
|
+
## 🚀 Quick Start
|
|
62
|
+
|
|
63
|
+
### Method 1: Dynamic Icon Component
|
|
64
|
+
|
|
65
|
+
Perfect for rendering icons dynamically with full type safety.
|
|
66
|
+
|
|
67
|
+
```tsx
|
|
68
|
+
import { Icon } from '@icon-craft/react-ts';
|
|
69
|
+
|
|
70
|
+
function App() {
|
|
71
|
+
return (
|
|
72
|
+
<div>
|
|
73
|
+
<Icon name="home" size={24} />
|
|
74
|
+
<Icon name="heart" size={32} color="red" />
|
|
75
|
+
<Icon name="search" size={24} color="#0066cc" />
|
|
76
|
+
</div>
|
|
77
|
+
);
|
|
78
|
+
}
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
### Method 2: Direct Icon Components
|
|
82
|
+
|
|
83
|
+
Best for static icons with full TypeScript support and tree-shaking optimization.
|
|
84
|
+
|
|
85
|
+
```tsx
|
|
86
|
+
import { IconHome, IconHeart, IconSearch } from '@icon-craft/react-ts';
|
|
87
|
+
|
|
88
|
+
function App() {
|
|
89
|
+
return (
|
|
90
|
+
<div>
|
|
91
|
+
<IconHome size={24} />
|
|
92
|
+
<IconHeart size={32} color="red" />
|
|
93
|
+
<IconSearch size={24} color="#0066cc" />
|
|
94
|
+
</div>
|
|
95
|
+
);
|
|
96
|
+
}
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
---
|
|
100
|
+
|
|
101
|
+
## 📘 TypeScript Features
|
|
102
|
+
|
|
103
|
+
### Full Type Definitions
|
|
104
|
+
|
|
105
|
+
All components come with complete TypeScript definitions:
|
|
106
|
+
|
|
107
|
+
```tsx
|
|
108
|
+
import { Icon, IconProps, IconComponentProps } from '@icon-craft/react-ts';
|
|
109
|
+
|
|
110
|
+
// Icon component with full type safety
|
|
111
|
+
const MyIcon: React.FC<IconProps> = (props) => {
|
|
112
|
+
return <Icon {...props} />;
|
|
113
|
+
};
|
|
114
|
+
|
|
115
|
+
// Custom icon wrapper with typed props
|
|
116
|
+
interface CustomIconProps extends IconComponentProps {
|
|
117
|
+
tooltip?: string;
|
|
118
|
+
variant?: 'primary' | 'secondary';
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
const CustomIcon: React.FC<CustomIconProps> = ({
|
|
122
|
+
tooltip,
|
|
123
|
+
variant = 'primary',
|
|
124
|
+
size = 24,
|
|
125
|
+
...props
|
|
126
|
+
}) => {
|
|
127
|
+
const color = variant === 'primary' ? '#007bff' : '#6c757d';
|
|
128
|
+
|
|
129
|
+
return (
|
|
130
|
+
<div title={tooltip}>
|
|
131
|
+
<Icon {...props} size={size} color={color} />
|
|
132
|
+
</div>
|
|
133
|
+
);
|
|
134
|
+
};
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
### IntelliSense Autocomplete
|
|
138
|
+
|
|
139
|
+
Get full autocomplete support in VS Code and other IDEs:
|
|
140
|
+
|
|
141
|
+
```tsx
|
|
142
|
+
import { Icon } from '@icon-craft/react-ts';
|
|
143
|
+
|
|
144
|
+
// Type "Icon" and get autocomplete for all 3475+ icon names
|
|
145
|
+
<Icon name="ho..." />
|
|
146
|
+
// ↑ Shows: home, hospital, hotel, hourglass, etc.
|
|
147
|
+
|
|
148
|
+
// Get autocomplete for all props
|
|
149
|
+
<Icon
|
|
150
|
+
name="home"
|
|
151
|
+
size={...} // number | string
|
|
152
|
+
color={...} // string
|
|
153
|
+
strokeWidth={...} // number
|
|
154
|
+
className={...} // string
|
|
155
|
+
style={...} // React.CSSProperties
|
|
156
|
+
onClick={...} // (event: React.MouseEvent) => void
|
|
157
|
+
/>
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
### Type-Safe Icon Names
|
|
161
|
+
|
|
162
|
+
```tsx
|
|
163
|
+
import { iconNames, IconName } from '@icon-craft/react-ts';
|
|
164
|
+
|
|
165
|
+
// IconName is a union type of all available icon names
|
|
166
|
+
const myIcon: IconName = 'home'; // ✅ Valid
|
|
167
|
+
const invalid: IconName = 'nonexistent'; // ❌ TypeScript error
|
|
168
|
+
|
|
169
|
+
// Get all icon names as typed array
|
|
170
|
+
const allIcons: string[] = iconNames;
|
|
171
|
+
|
|
172
|
+
// Type-safe icon mapping
|
|
173
|
+
const iconConfig: Record<IconName, { color: string; size: number }> = {
|
|
174
|
+
'home': { color: 'blue', size: 24 },
|
|
175
|
+
'heart': { color: 'red', size: 32 },
|
|
176
|
+
// TypeScript ensures you only use valid icon names
|
|
177
|
+
};
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
### Strongly Typed Props
|
|
181
|
+
|
|
182
|
+
```tsx
|
|
183
|
+
import { Icon, IconHome } from '@icon-craft/react-ts';
|
|
184
|
+
import { SVGProps } from 'react';
|
|
185
|
+
|
|
186
|
+
// All icon props are fully typed
|
|
187
|
+
interface MyComponentProps {
|
|
188
|
+
iconName: string; // Or use IconName type for stricter typing
|
|
189
|
+
iconSize?: number;
|
|
190
|
+
iconColor?: string;
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
const MyComponent: React.FC<MyComponentProps> = ({
|
|
194
|
+
iconName,
|
|
195
|
+
iconSize = 24,
|
|
196
|
+
iconColor = 'currentColor'
|
|
197
|
+
}) => {
|
|
198
|
+
return (
|
|
199
|
+
<Icon
|
|
200
|
+
name={iconName}
|
|
201
|
+
size={iconSize}
|
|
202
|
+
color={iconColor}
|
|
203
|
+
// TypeScript knows all available props
|
|
204
|
+
onClick={(e) => console.log('Clicked')} // Fully typed event
|
|
205
|
+
/>
|
|
206
|
+
);
|
|
207
|
+
};
|
|
208
|
+
|
|
209
|
+
// Direct components are also fully typed
|
|
210
|
+
const TypedIcon: React.FC<{ size: number }> = ({ size }) => {
|
|
211
|
+
return (
|
|
212
|
+
<IconHome
|
|
213
|
+
size={size}
|
|
214
|
+
// All SVG props are available and typed
|
|
215
|
+
aria-label="Home"
|
|
216
|
+
role="img"
|
|
217
|
+
/>
|
|
218
|
+
);
|
|
219
|
+
};
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
---
|
|
223
|
+
|
|
224
|
+
## 📖 Documentation
|
|
225
|
+
|
|
226
|
+
### Icon Component Props
|
|
227
|
+
|
|
228
|
+
All icons accept standard SVG attributes plus these convenience props:
|
|
229
|
+
|
|
230
|
+
| Prop | Type | Default | Description |
|
|
231
|
+
|------|------|---------|-------------|
|
|
232
|
+
| `name` | `string` | - | **Required** for `<Icon/>`. Icon identifier (e.g., "home", "heart") |
|
|
233
|
+
| `size` | `number \| string` | `24` | Width and height in pixels |
|
|
234
|
+
| `color` | `string` | `'currentColor'` | Icon color (any valid CSS color) |
|
|
235
|
+
| `strokeWidth` | `number` | `2` | Stroke width for outline icons |
|
|
236
|
+
| `className` | `string` | `''` | Additional CSS classes |
|
|
237
|
+
| `style` | `React.CSSProperties` | - | Inline styles object |
|
|
238
|
+
| `onClick` | `(e: React.MouseEvent) => void` | - | Click event handler |
|
|
239
|
+
| `...props` | `SVGProps<SVGSVGElement>` | - | Any other valid SVG attributes |
|
|
240
|
+
|
|
241
|
+
---
|
|
242
|
+
|
|
243
|
+
## 💡 Usage Examples
|
|
244
|
+
|
|
245
|
+
### Basic Usage
|
|
246
|
+
|
|
247
|
+
```tsx
|
|
248
|
+
import { Icon } from '@icon-craft/react-ts';
|
|
249
|
+
|
|
250
|
+
// Simple icon
|
|
251
|
+
<Icon name="home" />
|
|
252
|
+
|
|
253
|
+
// Custom size
|
|
254
|
+
<Icon name="heart" size={48} />
|
|
255
|
+
|
|
256
|
+
// Custom color
|
|
257
|
+
<Icon name="star" color="gold" />
|
|
258
|
+
|
|
259
|
+
// With stroke width (for outline icons)
|
|
260
|
+
<Icon name="circle" strokeWidth={3} />
|
|
261
|
+
|
|
262
|
+
// With CSS classes
|
|
263
|
+
<Icon name="search" className="my-custom-class" />
|
|
264
|
+
|
|
265
|
+
// With inline styles
|
|
266
|
+
<Icon name="settings" style={{ marginRight: '10px' }} />
|
|
267
|
+
|
|
268
|
+
// With click handler (fully typed)
|
|
269
|
+
<Icon
|
|
270
|
+
name="menu"
|
|
271
|
+
onClick={(e: React.MouseEvent<SVGSVGElement>) => {
|
|
272
|
+
console.log('Menu clicked!', e.currentTarget);
|
|
273
|
+
}}
|
|
274
|
+
/>
|
|
275
|
+
```
|
|
276
|
+
|
|
277
|
+
### Type-Safe Icon Button Component
|
|
278
|
+
|
|
279
|
+
```tsx
|
|
280
|
+
import { Icon, IconProps } from '@icon-craft/react-ts';
|
|
281
|
+
import React from 'react';
|
|
282
|
+
|
|
283
|
+
interface IconButtonProps {
|
|
284
|
+
icon: string;
|
|
285
|
+
label: string;
|
|
286
|
+
onClick: () => void;
|
|
287
|
+
variant?: 'primary' | 'secondary' | 'danger';
|
|
288
|
+
size?: number;
|
|
289
|
+
disabled?: boolean;
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
const IconButton: React.FC<IconButtonProps> = ({
|
|
293
|
+
icon,
|
|
294
|
+
label,
|
|
295
|
+
onClick,
|
|
296
|
+
variant = 'primary',
|
|
297
|
+
size = 20,
|
|
298
|
+
disabled = false
|
|
299
|
+
}) => {
|
|
300
|
+
const colors = {
|
|
301
|
+
primary: '#007bff',
|
|
302
|
+
secondary: '#6c757d',
|
|
303
|
+
danger: '#dc3545'
|
|
304
|
+
};
|
|
305
|
+
|
|
306
|
+
return (
|
|
307
|
+
<button
|
|
308
|
+
onClick={onClick}
|
|
309
|
+
disabled={disabled}
|
|
310
|
+
style={{
|
|
311
|
+
display: 'flex',
|
|
312
|
+
alignItems: 'center',
|
|
313
|
+
gap: '8px',
|
|
314
|
+
padding: '10px 20px',
|
|
315
|
+
border: 'none',
|
|
316
|
+
borderRadius: '8px',
|
|
317
|
+
background: disabled ? '#ccc' : colors[variant],
|
|
318
|
+
color: 'white',
|
|
319
|
+
cursor: disabled ? 'not-allowed' : 'pointer',
|
|
320
|
+
fontSize: '16px',
|
|
321
|
+
opacity: disabled ? 0.6 : 1
|
|
322
|
+
}}
|
|
323
|
+
>
|
|
324
|
+
<Icon name={icon} size={size} />
|
|
325
|
+
{label}
|
|
326
|
+
</button>
|
|
327
|
+
);
|
|
328
|
+
};
|
|
329
|
+
|
|
330
|
+
// Usage with full type safety
|
|
331
|
+
<IconButton
|
|
332
|
+
icon="download"
|
|
333
|
+
label="Download"
|
|
334
|
+
onClick={() => console.log('Download')}
|
|
335
|
+
variant="primary"
|
|
336
|
+
/>
|
|
337
|
+
<IconButton
|
|
338
|
+
icon="trash"
|
|
339
|
+
label="Delete"
|
|
340
|
+
onClick={() => console.log('Delete')}
|
|
341
|
+
variant="danger"
|
|
342
|
+
/>
|
|
343
|
+
```
|
|
344
|
+
|
|
345
|
+
### With Tailwind CSS + TypeScript
|
|
346
|
+
|
|
347
|
+
```tsx
|
|
348
|
+
import { Icon } from '@icon-craft/react-ts';
|
|
349
|
+
import { FC } from 'react';
|
|
350
|
+
|
|
351
|
+
const IconGallery: FC = () => {
|
|
352
|
+
return (
|
|
353
|
+
<div className="flex gap-4 p-8">
|
|
354
|
+
<Icon
|
|
355
|
+
name="home"
|
|
356
|
+
className="w-6 h-6 text-blue-500 hover:text-blue-700 transition-colors cursor-pointer"
|
|
357
|
+
/>
|
|
358
|
+
<Icon
|
|
359
|
+
name="heart"
|
|
360
|
+
className="w-8 h-8 text-red-500 hover:scale-110 transition-transform cursor-pointer"
|
|
361
|
+
/>
|
|
362
|
+
<Icon
|
|
363
|
+
name="settings"
|
|
364
|
+
className="w-5 h-5 text-gray-600 dark:text-gray-300"
|
|
365
|
+
/>
|
|
366
|
+
</div>
|
|
367
|
+
);
|
|
368
|
+
};
|
|
369
|
+
|
|
370
|
+
export default IconGallery;
|
|
371
|
+
```
|
|
372
|
+
|
|
373
|
+
### Interactive Favorite Button (Type-Safe)
|
|
374
|
+
|
|
375
|
+
```tsx
|
|
376
|
+
import { useState, FC } from 'react';
|
|
377
|
+
import { Icon } from '@icon-craft/react-ts';
|
|
378
|
+
|
|
379
|
+
interface FavoriteButtonProps {
|
|
380
|
+
itemId: string;
|
|
381
|
+
initialFavorite?: boolean;
|
|
382
|
+
onToggle?: (isFavorite: boolean) => void;
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
const FavoriteButton: FC<FavoriteButtonProps> = ({
|
|
386
|
+
itemId,
|
|
387
|
+
initialFavorite = false,
|
|
388
|
+
onToggle
|
|
389
|
+
}) => {
|
|
390
|
+
const [isFavorite, setIsFavorite] = useState(initialFavorite);
|
|
391
|
+
|
|
392
|
+
const handleClick = () => {
|
|
393
|
+
const newState = !isFavorite;
|
|
394
|
+
setIsFavorite(newState);
|
|
395
|
+
onToggle?.(newState);
|
|
396
|
+
};
|
|
397
|
+
|
|
398
|
+
return (
|
|
399
|
+
<button
|
|
400
|
+
onClick={handleClick}
|
|
401
|
+
style={{
|
|
402
|
+
background: 'transparent',
|
|
403
|
+
border: 'none',
|
|
404
|
+
cursor: 'pointer',
|
|
405
|
+
padding: '8px',
|
|
406
|
+
borderRadius: '50%',
|
|
407
|
+
transition: 'transform 0.2s'
|
|
408
|
+
}}
|
|
409
|
+
onMouseEnter={(e) => e.currentTarget.style.transform = 'scale(1.1)'}
|
|
410
|
+
onMouseLeave={(e) => e.currentTarget.style.transform = 'scale(1)'}
|
|
411
|
+
aria-label={isFavorite ? 'Remove from favorites' : 'Add to favorites'}
|
|
412
|
+
>
|
|
413
|
+
<Icon
|
|
414
|
+
name="heart"
|
|
415
|
+
size={32}
|
|
416
|
+
color={isFavorite ? '#ff4444' : '#cccccc'}
|
|
417
|
+
style={{
|
|
418
|
+
fill: isFavorite ? '#ff4444' : 'none',
|
|
419
|
+
transition: 'all 0.3s ease'
|
|
420
|
+
}}
|
|
421
|
+
/>
|
|
422
|
+
</button>
|
|
423
|
+
);
|
|
424
|
+
};
|
|
425
|
+
|
|
426
|
+
export default FavoriteButton;
|
|
427
|
+
```
|
|
428
|
+
|
|
429
|
+
### Type-Safe Navigation Bar
|
|
430
|
+
|
|
431
|
+
```tsx
|
|
432
|
+
import { Icon } from '@icon-craft/react-ts';
|
|
433
|
+
import { FC } from 'react';
|
|
434
|
+
|
|
435
|
+
interface NavItem {
|
|
436
|
+
icon: string;
|
|
437
|
+
label: string;
|
|
438
|
+
path: string;
|
|
439
|
+
badge?: number;
|
|
440
|
+
}
|
|
441
|
+
|
|
442
|
+
const navItems: NavItem[] = [
|
|
443
|
+
{ icon: 'home', label: 'Home', path: '/' },
|
|
444
|
+
{ icon: 'search', label: 'Search', path: '/search' },
|
|
445
|
+
{ icon: 'bell', label: 'Notifications', path: '/notifications', badge: 3 },
|
|
446
|
+
{ icon: 'user', label: 'Profile', path: '/profile' },
|
|
447
|
+
{ icon: 'settings', label: 'Settings', path: '/settings' },
|
|
448
|
+
];
|
|
449
|
+
|
|
450
|
+
const Navbar: FC = () => {
|
|
451
|
+
return (
|
|
452
|
+
<nav style={{ display: 'flex', gap: '30px', padding: '20px' }}>
|
|
453
|
+
{navItems.map((item) => (
|
|
454
|
+
<a
|
|
455
|
+
key={item.path}
|
|
456
|
+
href={item.path}
|
|
457
|
+
style={{
|
|
458
|
+
display: 'flex',
|
|
459
|
+
flexDirection: 'column',
|
|
460
|
+
alignItems: 'center',
|
|
461
|
+
gap: '5px',
|
|
462
|
+
textDecoration: 'none',
|
|
463
|
+
color: '#333',
|
|
464
|
+
position: 'relative'
|
|
465
|
+
}}
|
|
466
|
+
>
|
|
467
|
+
<Icon name={item.icon} size={24} />
|
|
468
|
+
<span style={{ fontSize: '12px' }}>{item.label}</span>
|
|
469
|
+
{item.badge && (
|
|
470
|
+
<span style={{
|
|
471
|
+
position: 'absolute',
|
|
472
|
+
top: '-5px',
|
|
473
|
+
right: '-10px',
|
|
474
|
+
background: 'red',
|
|
475
|
+
color: 'white',
|
|
476
|
+
borderRadius: '50%',
|
|
477
|
+
width: '20px',
|
|
478
|
+
height: '20px',
|
|
479
|
+
display: 'flex',
|
|
480
|
+
alignItems: 'center',
|
|
481
|
+
justifyContent: 'center',
|
|
482
|
+
fontSize: '10px'
|
|
483
|
+
}}>
|
|
484
|
+
{item.badge}
|
|
485
|
+
</span>
|
|
486
|
+
)}
|
|
487
|
+
</a>
|
|
488
|
+
))}
|
|
489
|
+
</nav>
|
|
490
|
+
);
|
|
491
|
+
};
|
|
492
|
+
|
|
493
|
+
export default Navbar;
|
|
494
|
+
```
|
|
495
|
+
|
|
496
|
+
### Type-Safe Icon Gallery with Search
|
|
497
|
+
|
|
498
|
+
```tsx
|
|
499
|
+
import { useState, FC, ChangeEvent } from 'react';
|
|
500
|
+
import { iconNames, Icon } from '@icon-craft/react-ts';
|
|
501
|
+
|
|
502
|
+
const IconGallery: FC = () => {
|
|
503
|
+
const [search, setSearch] = useState<string>('');
|
|
504
|
+
const [selected, setSelected] = useState<string | null>(null);
|
|
505
|
+
|
|
506
|
+
const filteredIcons = iconNames.filter((name: string) =>
|
|
507
|
+
name.toLowerCase().includes(search.toLowerCase())
|
|
508
|
+
);
|
|
509
|
+
|
|
510
|
+
const handleSearchChange = (e: ChangeEvent<HTMLInputElement>) => {
|
|
511
|
+
setSearch(e.target.value);
|
|
512
|
+
};
|
|
513
|
+
|
|
514
|
+
return (
|
|
515
|
+
<div style={{ padding: '20px' }}>
|
|
516
|
+
<input
|
|
517
|
+
type="text"
|
|
518
|
+
placeholder="Search icons..."
|
|
519
|
+
value={search}
|
|
520
|
+
onChange={handleSearchChange}
|
|
521
|
+
style={{
|
|
522
|
+
width: '100%',
|
|
523
|
+
maxWidth: '400px',
|
|
524
|
+
padding: '12px',
|
|
525
|
+
fontSize: '16px',
|
|
526
|
+
border: '2px solid #ddd',
|
|
527
|
+
borderRadius: '8px',
|
|
528
|
+
marginBottom: '20px'
|
|
529
|
+
}}
|
|
530
|
+
/>
|
|
531
|
+
|
|
532
|
+
<div
|
|
533
|
+
style={{
|
|
534
|
+
display: 'grid',
|
|
535
|
+
gridTemplateColumns: 'repeat(auto-fill, minmax(100px, 1fr))',
|
|
536
|
+
gap: '15px'
|
|
537
|
+
}}
|
|
538
|
+
>
|
|
539
|
+
{filteredIcons.slice(0, 100).map((name: string) => (
|
|
540
|
+
<div
|
|
541
|
+
key={name}
|
|
542
|
+
onClick={() => setSelected(name)}
|
|
543
|
+
style={{
|
|
544
|
+
display: 'flex',
|
|
545
|
+
flexDirection: 'column',
|
|
546
|
+
alignItems: 'center',
|
|
547
|
+
gap: '8px',
|
|
548
|
+
padding: '15px',
|
|
549
|
+
border: selected === name ? '2px solid #007bff' : '1px solid #ddd',
|
|
550
|
+
borderRadius: '8px',
|
|
551
|
+
cursor: 'pointer',
|
|
552
|
+
transition: 'all 0.2s',
|
|
553
|
+
backgroundColor: selected === name ? '#f0f8ff' : 'white'
|
|
554
|
+
}}
|
|
555
|
+
onMouseEnter={(e) => {
|
|
556
|
+
e.currentTarget.style.borderColor = '#007bff';
|
|
557
|
+
e.currentTarget.style.transform = 'translateY(-2px)';
|
|
558
|
+
}}
|
|
559
|
+
onMouseLeave={(e) => {
|
|
560
|
+
if (selected !== name) {
|
|
561
|
+
e.currentTarget.style.borderColor = '#ddd';
|
|
562
|
+
}
|
|
563
|
+
e.currentTarget.style.transform = 'translateY(0)';
|
|
564
|
+
}}
|
|
565
|
+
>
|
|
566
|
+
<Icon name={name} size={32} />
|
|
567
|
+
<div style={{
|
|
568
|
+
fontSize: '10px',
|
|
569
|
+
textAlign: 'center',
|
|
570
|
+
wordBreak: 'break-word'
|
|
571
|
+
}}>
|
|
572
|
+
{name}
|
|
573
|
+
</div>
|
|
574
|
+
</div>
|
|
575
|
+
))}
|
|
576
|
+
</div>
|
|
577
|
+
|
|
578
|
+
{search && (
|
|
579
|
+
<div style={{ marginTop: '20px', color: '#666' }}>
|
|
580
|
+
Found {filteredIcons.length} icons matching "{search}"
|
|
581
|
+
</div>
|
|
582
|
+
)}
|
|
583
|
+
|
|
584
|
+
{selected && (
|
|
585
|
+
<div style={{
|
|
586
|
+
position: 'fixed',
|
|
587
|
+
bottom: '20px',
|
|
588
|
+
right: '20px',
|
|
589
|
+
padding: '15px 20px',
|
|
590
|
+
background: '#007bff',
|
|
591
|
+
color: 'white',
|
|
592
|
+
borderRadius: '8px',
|
|
593
|
+
boxShadow: '0 4px 12px rgba(0,0,0,0.15)'
|
|
594
|
+
}}>
|
|
595
|
+
Selected: <code style={{ fontWeight: 'bold' }}>{selected}</code>
|
|
596
|
+
</div>
|
|
597
|
+
)}
|
|
598
|
+
</div>
|
|
599
|
+
);
|
|
600
|
+
};
|
|
601
|
+
|
|
602
|
+
export default IconGallery;
|
|
603
|
+
```
|
|
604
|
+
|
|
605
|
+
### Generic Icon Component Wrapper
|
|
606
|
+
|
|
607
|
+
```tsx
|
|
608
|
+
import { Icon, IconProps } from '@icon-craft/react-ts';
|
|
609
|
+
import { FC } from 'react';
|
|
610
|
+
|
|
611
|
+
interface AnimatedIconProps extends Omit<IconProps, 'style'> {
|
|
612
|
+
animate?: boolean;
|
|
613
|
+
animationType?: 'spin' | 'pulse' | 'bounce';
|
|
614
|
+
}
|
|
615
|
+
|
|
616
|
+
const AnimatedIcon: FC<AnimatedIconProps> = ({
|
|
617
|
+
animate = false,
|
|
618
|
+
animationType = 'spin',
|
|
619
|
+
style,
|
|
620
|
+
...props
|
|
621
|
+
}) => {
|
|
622
|
+
const animations = {
|
|
623
|
+
spin: { animation: 'spin 1s linear infinite' },
|
|
624
|
+
pulse: { animation: 'pulse 2s ease-in-out infinite' },
|
|
625
|
+
bounce: { animation: 'bounce 1s ease-in-out infinite' }
|
|
626
|
+
};
|
|
627
|
+
|
|
628
|
+
return (
|
|
629
|
+
<Icon
|
|
630
|
+
{...props}
|
|
631
|
+
style={{
|
|
632
|
+
...style,
|
|
633
|
+
...(animate ? animations[animationType] : {})
|
|
634
|
+
}}
|
|
635
|
+
/>
|
|
636
|
+
);
|
|
637
|
+
};
|
|
638
|
+
|
|
639
|
+
// Usage
|
|
640
|
+
<AnimatedIcon name="loader" animate animationType="spin" />
|
|
641
|
+
<AnimatedIcon name="heart" animate animationType="pulse" color="red" />
|
|
642
|
+
```
|
|
643
|
+
|
|
644
|
+
---
|
|
645
|
+
|
|
646
|
+
## 📚 Available Icons
|
|
647
|
+
|
|
648
|
+
### Icon Categories
|
|
649
|
+
|
|
650
|
+
Icon-Craft includes **3475+ icons** across multiple categories:
|
|
651
|
+
|
|
652
|
+
- **UI & Navigation** - home, menu, settings, search, filter, more, etc.
|
|
653
|
+
- **Media Controls** - play, pause, stop, forward, rewind, volume, etc.
|
|
654
|
+
- **Communication** - mail, message, phone, chat, notification, etc.
|
|
655
|
+
- **E-commerce** - shopping-cart, credit-card, tag, dollar, wallet, etc.
|
|
656
|
+
- **Files & Folders** - file, folder, save, upload, download, cloud, etc.
|
|
657
|
+
- **Arrows & Directions** - arrow-up, arrow-down, chevron-right, etc.
|
|
658
|
+
- **Social Media** - facebook, twitter, instagram, github, linkedin, etc.
|
|
659
|
+
- **Weather** - sun, cloud, rain, snow, wind, moon, etc.
|
|
660
|
+
- **Devices** - smartphone, tablet, laptop, monitor, printer, etc.
|
|
661
|
+
- **Business** - briefcase, chart, graph, analytics, presentation, etc.
|
|
662
|
+
- **Health & Medical** - heart, medical, pill, hospital, etc.
|
|
663
|
+
- **Education** - book, graduation, pencil, etc.
|
|
664
|
+
- **And many more!**
|
|
665
|
+
|
|
666
|
+
### Finding Icons (Type-Safe)
|
|
667
|
+
|
|
668
|
+
```tsx
|
|
669
|
+
import { iconNames, iconMap, IconName } from '@icon-craft/react-ts';
|
|
670
|
+
|
|
671
|
+
// Get array of all icon names (fully typed)
|
|
672
|
+
const allIcons: string[] = iconNames;
|
|
673
|
+
|
|
674
|
+
// Get icon name to component name mapping
|
|
675
|
+
const mapping: Record<string, string> = iconMap;
|
|
676
|
+
|
|
677
|
+
// Type-safe icon name
|
|
678
|
+
const myIconName: IconName = 'home';
|
|
679
|
+
|
|
680
|
+
// Search for specific icons with type safety
|
|
681
|
+
const searchIcons = (query: string): string[] => {
|
|
682
|
+
return iconNames.filter(name => name.includes(query));
|
|
683
|
+
};
|
|
684
|
+
|
|
685
|
+
const arrowIcons = searchIcons('arrow');
|
|
686
|
+
console.log(arrowIcons);
|
|
687
|
+
// ['arrow-up', 'arrow-down', 'arrow-left', 'arrow-right', ...]
|
|
688
|
+
```
|
|
689
|
+
|
|
690
|
+
### Popular Icons
|
|
691
|
+
|
|
692
|
+
```tsx
|
|
693
|
+
// UI & Navigation
|
|
694
|
+
<Icon name="home" />
|
|
695
|
+
<Icon name="menu" />
|
|
696
|
+
<Icon name="search" />
|
|
697
|
+
<Icon name="settings" />
|
|
698
|
+
<Icon name="user" />
|
|
699
|
+
<Icon name="bell" />
|
|
700
|
+
<Icon name="star" />
|
|
701
|
+
|
|
702
|
+
// Actions
|
|
703
|
+
<Icon name="edit" />
|
|
704
|
+
<Icon name="trash" />
|
|
705
|
+
<Icon name="save" />
|
|
706
|
+
<Icon name="download" />
|
|
707
|
+
<Icon name="upload" />
|
|
708
|
+
<Icon name="share" />
|
|
709
|
+
<Icon name="copy" />
|
|
710
|
+
|
|
711
|
+
// Media
|
|
712
|
+
<Icon name="play" />
|
|
713
|
+
<Icon name="pause" />
|
|
714
|
+
<Icon name="stop" />
|
|
715
|
+
<Icon name="volume" />
|
|
716
|
+
<Icon name="camera" />
|
|
717
|
+
<Icon name="image" />
|
|
718
|
+
<Icon name="video" />
|
|
719
|
+
|
|
720
|
+
// Communication
|
|
721
|
+
<Icon name="mail" />
|
|
722
|
+
<Icon name="message" />
|
|
723
|
+
<Icon name="phone" />
|
|
724
|
+
<Icon name="chat" />
|
|
725
|
+
|
|
726
|
+
// Arrows
|
|
727
|
+
<Icon name="arrow-up" />
|
|
728
|
+
<Icon name="arrow-down" />
|
|
729
|
+
<Icon name="arrow-left" />
|
|
730
|
+
<Icon name="arrow-right" />
|
|
731
|
+
<Icon name="chevron-up" />
|
|
732
|
+
<Icon name="chevron-down" />
|
|
733
|
+
|
|
734
|
+
// Social
|
|
735
|
+
<Icon name="github" />
|
|
736
|
+
<Icon name="twitter" />
|
|
737
|
+
<Icon name="facebook" />
|
|
738
|
+
<Icon name="instagram" />
|
|
739
|
+
<Icon name="linkedin" />
|
|
740
|
+
```
|
|
741
|
+
|
|
742
|
+
---
|
|
743
|
+
|
|
744
|
+
## 🎯 JavaScript Version
|
|
745
|
+
|
|
746
|
+
Need a JavaScript-only version? Check out:
|
|
747
|
+
|
|
748
|
+
```bash
|
|
749
|
+
npm install @icon-craft/react
|
|
750
|
+
```
|
|
751
|
+
|
|
752
|
+
The JavaScript version includes:
|
|
753
|
+
- Same 3475+ icons
|
|
754
|
+
- Same API and features
|
|
755
|
+
- No TypeScript overhead
|
|
756
|
+
- Perfect for pure JS projects
|
|
757
|
+
|
|
758
|
+
[View @icon-craft/react on NPM →](https://www.npmjs.com/package/@icon-craft/react)
|
|
759
|
+
|
|
760
|
+
---
|
|
761
|
+
|
|
762
|
+
## 📦 Bundle Size & Performance
|
|
763
|
+
|
|
764
|
+
### Package Size
|
|
765
|
+
- **Source Package**: ~23MB (includes all 3475 icons)
|
|
766
|
+
- **Per Icon (after tree-shaking)**: ~2-5KB
|
|
767
|
+
- **Runtime Dependencies**: 0 (only React peer dependency)
|
|
768
|
+
- **TypeScript Definitions**: Included
|
|
769
|
+
|
|
770
|
+
### Optimization Tips
|
|
771
|
+
|
|
772
|
+
#### ✅ Best Practice (Tree-shakeable)
|
|
773
|
+
```tsx
|
|
774
|
+
// Import only what you need
|
|
775
|
+
import { IconHome, IconHeart, IconSearch } from '@icon-craft/react-ts';
|
|
776
|
+
```
|
|
777
|
+
|
|
778
|
+
#### ⚠️ Less Optimal
|
|
779
|
+
```tsx
|
|
780
|
+
// Imports everything
|
|
781
|
+
import * as Icons from '@icon-craft/react-ts';
|
|
782
|
+
```
|
|
783
|
+
|
|
784
|
+
#### 🚀 Code Splitting (Advanced)
|
|
785
|
+
```tsx
|
|
786
|
+
import { lazy, Suspense } from 'react';
|
|
787
|
+
|
|
788
|
+
const Icon = lazy(() =>
|
|
789
|
+
import('@icon-craft/react-ts').then(m => ({ default: m.Icon }))
|
|
790
|
+
);
|
|
791
|
+
|
|
792
|
+
function App() {
|
|
793
|
+
return (
|
|
794
|
+
<Suspense fallback={<div>Loading...</div>}>
|
|
795
|
+
<Icon name="home" />
|
|
796
|
+
</Suspense>
|
|
797
|
+
);
|
|
798
|
+
}
|
|
799
|
+
```
|
|
800
|
+
|
|
801
|
+
### Build Tool Support
|
|
802
|
+
|
|
803
|
+
Icon-Craft TypeScript works seamlessly with:
|
|
804
|
+
- ✅ Webpack 5
|
|
805
|
+
- ✅ Vite
|
|
806
|
+
- ✅ Rollup
|
|
807
|
+
- ✅ Parcel
|
|
808
|
+
- ✅ esbuild
|
|
809
|
+
- ✅ Create React App (TypeScript template)
|
|
810
|
+
- ✅ Next.js (with TypeScript)
|
|
811
|
+
- ✅ Remix (with TypeScript)
|
|
812
|
+
- ✅ Gatsby (with TypeScript)
|
|
813
|
+
|
|
814
|
+
---
|
|
815
|
+
|
|
816
|
+
## 🌍 Browser Support
|
|
817
|
+
|
|
818
|
+
- ✅ Chrome (latest)
|
|
819
|
+
- ✅ Firefox (latest)
|
|
820
|
+
- ✅ Safari (latest)
|
|
821
|
+
- ✅ Edge (latest)
|
|
822
|
+
- ✅ Opera (latest)
|
|
823
|
+
- ⚠️ IE 11 (with polyfills)
|
|
824
|
+
|
|
825
|
+
**Requirements:**
|
|
826
|
+
- Modern browsers with SVG support
|
|
827
|
+
- React 16.8+ (Hooks support)
|
|
828
|
+
- TypeScript 4.0+ (for best experience)
|
|
829
|
+
|
|
830
|
+
---
|
|
831
|
+
|
|
832
|
+
## 🤔 FAQ
|
|
833
|
+
|
|
834
|
+
### Why TypeScript?
|
|
835
|
+
|
|
836
|
+
TypeScript provides:
|
|
837
|
+
- 🔒 **Type Safety** - Catch errors before runtime
|
|
838
|
+
- 💡 **IntelliSense** - Autocomplete in your IDE
|
|
839
|
+
- 📚 **Self-Documenting** - Props are documented via types
|
|
840
|
+
- 🔄 **Refactoring** - Safe and easy code changes
|
|
841
|
+
- 🐛 **Fewer Bugs** - Many bugs caught at compile time
|
|
842
|
+
|
|
843
|
+
### How is this different from @icon-craft/react?
|
|
844
|
+
|
|
845
|
+
| Feature | @icon-craft/react-ts | @icon-craft/react |
|
|
846
|
+
|---------|---------------------|-------------------|
|
|
847
|
+
| **TypeScript** | ✅ Full support | ❌ No types |
|
|
848
|
+
| **IntelliSense** | ✅ Complete | ⚠️ Limited |
|
|
849
|
+
| **Type Safety** | ✅ Compile-time | ❌ Runtime only |
|
|
850
|
+
| **Bundle Size** | Same | Same |
|
|
851
|
+
| **Icons** | 3475+ | 3475+ |
|
|
852
|
+
| **Best For** | TS/TSX projects | JS/JSX projects |
|
|
853
|
+
|
|
854
|
+
### Can I use this in a JavaScript project?
|
|
855
|
+
|
|
856
|
+
Yes, but you'll lose TypeScript benefits. For JavaScript projects, we recommend [@icon-craft/react](https://www.npmjs.com/package/@icon-craft/react).
|
|
857
|
+
|
|
858
|
+
### Does this work with Next.js?
|
|
859
|
+
|
|
860
|
+
Yes! Works perfectly with Next.js TypeScript:
|
|
861
|
+
|
|
862
|
+
```tsx
|
|
863
|
+
// app/page.tsx (Next.js 13+)
|
|
864
|
+
import { Icon } from '@icon-craft/react-ts';
|
|
865
|
+
|
|
866
|
+
export default function Home() {
|
|
867
|
+
return <Icon name="home" size={32} />;
|
|
868
|
+
}
|
|
869
|
+
```
|
|
870
|
+
|
|
871
|
+
### How do I get autocomplete for icon names?
|
|
872
|
+
|
|
873
|
+
Just start typing in your IDE (VS Code, WebStorm, etc.):
|
|
874
|
+
|
|
875
|
+
```tsx
|
|
876
|
+
<Icon name="ho..." />
|
|
877
|
+
// ↑ Autocomplete shows: home, hospital, hotel, etc.
|
|
878
|
+
```
|
|
879
|
+
|
|
880
|
+
Make sure your IDE has TypeScript support enabled.
|
|
881
|
+
|
|
882
|
+
### Can I use this with strict mode?
|
|
883
|
+
|
|
884
|
+
Yes! Icon-Craft is fully compatible with TypeScript strict mode:
|
|
885
|
+
|
|
886
|
+
```json
|
|
887
|
+
// tsconfig.json
|
|
888
|
+
{
|
|
889
|
+
"compilerOptions": {
|
|
890
|
+
"strict": true
|
|
891
|
+
}
|
|
892
|
+
}
|
|
893
|
+
```
|
|
894
|
+
|
|
895
|
+
---
|
|
896
|
+
|
|
897
|
+
## 🔄 Migration Guide
|
|
898
|
+
|
|
899
|
+
### From @icon-craft/react (JavaScript)
|
|
900
|
+
|
|
901
|
+
```tsx
|
|
902
|
+
// Before (JavaScript)
|
|
903
|
+
import { Icon, IconHome } from '@icon-craft/react';
|
|
904
|
+
|
|
905
|
+
// After (TypeScript)
|
|
906
|
+
import { Icon, IconHome } from '@icon-craft/react-ts';
|
|
907
|
+
|
|
908
|
+
// API is identical, just add types!
|
|
909
|
+
```
|
|
910
|
+
|
|
911
|
+
### From react-icons
|
|
912
|
+
|
|
913
|
+
```tsx
|
|
914
|
+
// Before (react-icons)
|
|
915
|
+
import { FaHome, FaHeart } from 'react-icons/fa';
|
|
916
|
+
<FaHome size={24} />
|
|
917
|
+
|
|
918
|
+
// After (icon-craft TypeScript)
|
|
919
|
+
import { IconHome, IconHeart } from '@icon-craft/react-ts';
|
|
920
|
+
<IconHome size={24} />
|
|
921
|
+
```
|
|
922
|
+
|
|
923
|
+
### From Feather Icons
|
|
924
|
+
|
|
925
|
+
```tsx
|
|
926
|
+
// Before (react-feather)
|
|
927
|
+
import { Home, Heart } from 'react-feather';
|
|
928
|
+
<Home size={24} />
|
|
929
|
+
|
|
930
|
+
// After (icon-craft TypeScript)
|
|
931
|
+
import { IconHome, IconHeart } from '@icon-craft/react-ts';
|
|
932
|
+
<IconHome size={24} />
|
|
933
|
+
```
|
|
934
|
+
|
|
935
|
+
---
|
|
936
|
+
|
|
937
|
+
## ⚖️ Legal & Attribution
|
|
938
|
+
|
|
939
|
+
### Licensing
|
|
940
|
+
|
|
941
|
+
This library is **MIT licensed**. It does not redistribute original icon packages but transforms and generates icons into a unified React component format with TypeScript definitions.
|
|
942
|
+
|
|
943
|
+
### Icon Sources
|
|
944
|
+
|
|
945
|
+
Icon-Craft combines icons from two excellent open-source projects:
|
|
946
|
+
|
|
947
|
+
#### **Feather Icons** — MIT License
|
|
948
|
+
- Source: https://feathericons.com
|
|
949
|
+
- Repository: https://github.com/feathericons/feather
|
|
950
|
+
- License: MIT (allows modification and redistribution)
|
|
951
|
+
|
|
952
|
+
#### **Remix Icon** — Apache License 2.0
|
|
953
|
+
- Source: https://remixicon.com
|
|
954
|
+
- Repository: https://github.com/Remix-Design/RemixIcon
|
|
955
|
+
- License: Apache 2.0 (allows modification and redistribution)
|
|
956
|
+
|
|
957
|
+
Both licenses **explicitly permit** modification, redistribution, and commercial use.
|
|
958
|
+
|
|
959
|
+
### Third-Party Notices
|
|
960
|
+
|
|
961
|
+
Full license texts are included in the [LICENSE](./LICENSE) file.
|
|
962
|
+
|
|
963
|
+
---
|
|
964
|
+
|
|
965
|
+
## 🤝 Contributing
|
|
966
|
+
|
|
967
|
+
Contributions, issues, and feature requests are welcome!
|
|
968
|
+
|
|
969
|
+
### How to Contribute
|
|
970
|
+
|
|
971
|
+
1. Fork the repository
|
|
972
|
+
2. Create your feature branch (`git checkout -b feature/amazing-feature`)
|
|
973
|
+
3. Commit your changes (`git commit -m 'Add some amazing feature'`)
|
|
974
|
+
4. Push to the branch (`git push origin feature/amazing-feature`)
|
|
975
|
+
5. Open a Pull Request
|
|
976
|
+
|
|
977
|
+
### Reporting Issues
|
|
978
|
+
|
|
979
|
+
Found a bug or have a suggestion? [Open an issue](https://github.com/PATEL-KRISH-0/icon-craft/issues)
|
|
980
|
+
|
|
981
|
+
---
|
|
982
|
+
|
|
983
|
+
## 📊 Stats & Links
|
|
984
|
+
|
|
985
|
+
- 📦 [NPM Package](https://www.npmjs.com/package/@icon-craft/react-ts)
|
|
986
|
+
- 🐙 [GitHub Repository](https://github.com/PATEL-KRISH-0/icon-craft)
|
|
987
|
+
- 🐛 [Report Issues](https://github.com/PATEL-KRISH-0/icon-craft/issues)
|
|
988
|
+
- 💬 [Discussions](https://github.com/PATEL-KRISH-0/icon-craft/discussions)
|
|
989
|
+
|
|
990
|
+
---
|
|
991
|
+
|
|
992
|
+
## 🙏 Credits
|
|
993
|
+
|
|
994
|
+
- **Feather Icons** - [feathericons.com](https://feathericons.com/)
|
|
995
|
+
- **Remix Icon** - [remixicon.com](https://remixicon.com/)
|
|
996
|
+
- **Built with ❤️ by [Krish Patel](https://github.com/PATEL-KRISH-0)**
|
|
997
|
+
|
|
998
|
+
---
|
|
999
|
+
|
|
1000
|
+
## 📄 License
|
|
1001
|
+
|
|
1002
|
+
MIT License © 2026 Krish Patel
|
|
1003
|
+
|
|
1004
|
+
See the [LICENSE](./LICENSE) file for complete details.
|
|
1005
|
+
|
|
1006
|
+
---
|
|
1007
|
+
|
|
1008
|
+
<div align="center">
|
|
1009
|
+
|
|
1010
|
+
**Made with ❤️ and TypeScript by [Krish Patel](https://github.com/PATEL-KRISH-0)**
|
|
1011
|
+
|
|
1012
|
+
If you find Icon-Craft useful, please consider giving it a ⭐️ on [GitHub](https://github.com/PATEL-KRISH-0/icon-craft)!
|
|
1013
|
+
|
|
1014
|
+
---
|
|
1015
|
+
|
|
1016
|
+
**[@icon-craft/react-ts](https://www.npmjs.com/package/@icon-craft/react-ts)** · **[@icon-craft/react](https://www.npmjs.com/package/@icon-craft/react)** · **[GitHub](https://github.com/PATEL-KRISH-0/icon-craft)**
|
|
1017
|
+
|
|
1018
|
+
</div>
|