vectify 2.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 +21 -0
- package/README.md +679 -0
- package/README.zh-CN.md +683 -0
- package/dist/chunk-4BWKFV7W.mjs +1311 -0
- package/dist/chunk-CIKTK6HI.mjs +96 -0
- package/dist/cli.d.mts +1 -0
- package/dist/cli.d.ts +1 -0
- package/dist/cli.js +1483 -0
- package/dist/cli.mjs +56 -0
- package/dist/helpers-UPZEBRGK.mjs +26 -0
- package/dist/index.d.mts +281 -0
- package/dist/index.d.ts +281 -0
- package/dist/index.js +1463 -0
- package/dist/index.mjs +27 -0
- package/dist/templates/angular/component.ts.hbs +121 -0
- package/dist/templates/angular/createIcon.ts.hbs +116 -0
- package/dist/templates/astro/component.astro.hbs +110 -0
- package/dist/templates/astro/createIcon.astro.hbs +111 -0
- package/dist/templates/lit/component.js.hbs +12 -0
- package/dist/templates/lit/component.ts.hbs +19 -0
- package/dist/templates/lit/createIcon.js.hbs +98 -0
- package/dist/templates/lit/createIcon.ts.hbs +99 -0
- package/dist/templates/preact/component.jsx.hbs +8 -0
- package/dist/templates/preact/component.tsx.hbs +11 -0
- package/dist/templates/preact/createIcon.jsx.hbs +101 -0
- package/dist/templates/preact/createIcon.tsx.hbs +121 -0
- package/dist/templates/qwik/component.jsx.hbs +7 -0
- package/dist/templates/qwik/component.tsx.hbs +8 -0
- package/dist/templates/qwik/createIcon.jsx.hbs +100 -0
- package/dist/templates/qwik/createIcon.tsx.hbs +111 -0
- package/dist/templates/react/component.jsx.hbs +8 -0
- package/dist/templates/react/component.tsx.hbs +11 -0
- package/dist/templates/react/createIcon.jsx.hbs +100 -0
- package/dist/templates/react/createIcon.tsx.hbs +117 -0
- package/dist/templates/solid/component.tsx.hbs +10 -0
- package/dist/templates/solid/createIcon.jsx.hbs +127 -0
- package/dist/templates/solid/createIcon.tsx.hbs +139 -0
- package/dist/templates/svelte/component.js.svelte.hbs +9 -0
- package/dist/templates/svelte/component.ts.svelte.hbs +10 -0
- package/dist/templates/svelte/icon.js.svelte.hbs +123 -0
- package/dist/templates/svelte/icon.ts.svelte.hbs +124 -0
- package/dist/templates/template-engine.ts +107 -0
- package/dist/templates/vanilla/component.ts.hbs +8 -0
- package/dist/templates/vanilla/createIcon.js.hbs +111 -0
- package/dist/templates/vanilla/createIcon.ts.hbs +124 -0
- package/dist/templates/vue/component.js.vue.hbs +21 -0
- package/dist/templates/vue/component.ts.vue.hbs +22 -0
- package/dist/templates/vue/icon.js.vue.hbs +155 -0
- package/dist/templates/vue/icon.ts.vue.hbs +157 -0
- package/package.json +78 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Xiaobing Zhu
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,679 @@
|
|
|
1
|
+
<div align="center">
|
|
2
|
+
|
|
3
|
+
# Vectify
|
|
4
|
+
|
|
5
|
+
A powerful command-line tool to generate framework-specific icon components from SVG files. Transform your SVG icons into fully-typed, customizable components for React, Vue, Svelte, and more.
|
|
6
|
+
|
|
7
|
+
English | [简体中文](./README.zh-CN.md)
|
|
8
|
+
|
|
9
|
+
[](https://www.npmjs.com/package/vectify)
|
|
10
|
+
[](https://opensource.org/licenses/MIT)
|
|
11
|
+
|
|
12
|
+
</div>
|
|
13
|
+
|
|
14
|
+
## 📑 Table of Contents
|
|
15
|
+
|
|
16
|
+
- [Features](#features)
|
|
17
|
+
- [Installation](#installation)
|
|
18
|
+
- [Quick Start](#quick-start)
|
|
19
|
+
- [CLI Commands](#cli-commands)
|
|
20
|
+
- [Configuration](#configuration)
|
|
21
|
+
- [Basic Options](#basic-options)
|
|
22
|
+
- [Generation Options](#generation-options)
|
|
23
|
+
- [Watch Mode](#watch-mode)
|
|
24
|
+
- [SVGO Configuration](#svgo-configuration)
|
|
25
|
+
- [Lifecycle Hooks](#lifecycle-hooks)
|
|
26
|
+
- [Component Props](#component-props)
|
|
27
|
+
- [Framework-Specific Notes](#framework-specific-notes)
|
|
28
|
+
- [Best Practices](#best-practices)
|
|
29
|
+
- [Advanced Usage](#advanced-usage)
|
|
30
|
+
- [Troubleshooting](#troubleshooting)
|
|
31
|
+
- [Migration Guide](#migration-guide)
|
|
32
|
+
- [Contributing](#contributing)
|
|
33
|
+
- [License](#license)
|
|
34
|
+
|
|
35
|
+
## Features
|
|
36
|
+
|
|
37
|
+
- **10+ Framework Support** - React, Vue, Svelte, Solid.js, Preact, Angular, Lit, Qwik, Astro, and Vanilla JS
|
|
38
|
+
- **TypeScript First** - Full TypeScript support with auto-generated type definitions
|
|
39
|
+
- **Automatic Optimization** - Built-in SVG optimization using SVGO
|
|
40
|
+
- **Flexible Customization** - Control size, color, stroke width, and more at runtime
|
|
41
|
+
- **Watch Mode** - Automatically regenerate components when SVG files change
|
|
42
|
+
- **Lifecycle Hooks** - Customize generation with beforeParse, afterGenerate, and onComplete hooks
|
|
43
|
+
- **Preview Generation** - Generate interactive HTML preview of all icons
|
|
44
|
+
- **Clean Output** - Automatically remove orphaned components when SVG files are deleted
|
|
45
|
+
- **Batch Processing** - Process multiple SVG files efficiently
|
|
46
|
+
|
|
47
|
+
## Installation
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
# Using npm
|
|
51
|
+
npm install -D vectify
|
|
52
|
+
|
|
53
|
+
# Using pnpm
|
|
54
|
+
pnpm add -D vectify
|
|
55
|
+
|
|
56
|
+
# Using yarn
|
|
57
|
+
yarn add -D vectify
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
## Quick Start
|
|
61
|
+
|
|
62
|
+
### 1. Initialize Configuration
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
npx vectify init
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
This will create a `vectify.config.ts` file in your project root. Select your target framework and configure the paths:
|
|
69
|
+
|
|
70
|
+
```typescript
|
|
71
|
+
import { defineConfig } from 'vectify'
|
|
72
|
+
|
|
73
|
+
export default defineConfig({
|
|
74
|
+
framework: 'react',
|
|
75
|
+
input: './icons',
|
|
76
|
+
output: './src/icons',
|
|
77
|
+
typescript: true,
|
|
78
|
+
optimize: true,
|
|
79
|
+
generateOptions: {
|
|
80
|
+
index: true,
|
|
81
|
+
types: true,
|
|
82
|
+
preview: true,
|
|
83
|
+
},
|
|
84
|
+
})
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
### 2. Add SVG Files
|
|
88
|
+
|
|
89
|
+
Place your SVG files in the configured input directory (default: `./icons`):
|
|
90
|
+
|
|
91
|
+
```
|
|
92
|
+
icons/
|
|
93
|
+
├── arrow-right.svg
|
|
94
|
+
├── user.svg
|
|
95
|
+
└── settings.svg
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
### 3. Generate Components
|
|
99
|
+
|
|
100
|
+
```bash
|
|
101
|
+
npx vectify generate
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
This will generate icon components in your output directory:
|
|
105
|
+
|
|
106
|
+
```
|
|
107
|
+
src/icons/
|
|
108
|
+
├── ArrowRight.tsx
|
|
109
|
+
├── User.tsx
|
|
110
|
+
├── Settings.tsx
|
|
111
|
+
├── index.ts
|
|
112
|
+
└── Icon.tsx
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
### 4. Use in Your Code
|
|
116
|
+
|
|
117
|
+
```tsx
|
|
118
|
+
import { ArrowRight, User, Settings } from './icons'
|
|
119
|
+
|
|
120
|
+
function App() {
|
|
121
|
+
return (
|
|
122
|
+
<div>
|
|
123
|
+
<ArrowRight size={24} color="blue" />
|
|
124
|
+
<User size={32} color="#333" strokeWidth={1.5} />
|
|
125
|
+
<Settings className="icon" />
|
|
126
|
+
</div>
|
|
127
|
+
)
|
|
128
|
+
}
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
## CLI Commands
|
|
132
|
+
|
|
133
|
+
### `vectify init`
|
|
134
|
+
|
|
135
|
+
Initialize a new configuration file.
|
|
136
|
+
|
|
137
|
+
```bash
|
|
138
|
+
npx vectify init [options]
|
|
139
|
+
|
|
140
|
+
Options:
|
|
141
|
+
-f, --force Overwrite existing config file
|
|
142
|
+
-o, --output Output path for config file (default: vectify.config.ts)
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
### `vectify generate`
|
|
146
|
+
|
|
147
|
+
Generate icon components from SVG files.
|
|
148
|
+
|
|
149
|
+
```bash
|
|
150
|
+
npx vectify generate [options]
|
|
151
|
+
|
|
152
|
+
Options:
|
|
153
|
+
-c, --config Path to config file (default: vectify.config.ts)
|
|
154
|
+
--dry-run Preview what will be generated without writing files
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
### `vectify watch`
|
|
158
|
+
|
|
159
|
+
Watch for changes and regenerate automatically.
|
|
160
|
+
|
|
161
|
+
```bash
|
|
162
|
+
npx vectify watch [options]
|
|
163
|
+
|
|
164
|
+
Options:
|
|
165
|
+
-c, --config Path to config file (default: vectify.config.ts)
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
## Configuration
|
|
169
|
+
|
|
170
|
+
### Complete Configuration Reference
|
|
171
|
+
|
|
172
|
+
All available options for `defineConfig()` are documented in the tables below.
|
|
173
|
+
|
|
174
|
+
#### Core Configuration
|
|
175
|
+
|
|
176
|
+
| Parameter | Type | Default | Required | Description | Example |
|
|
177
|
+
|-----------|------|---------|----------|-------------|----------|
|
|
178
|
+
| `framework` | `'react'` \| `'vue'` \| `'svelte'` \| `'solid'` \| `'preact'` \| `'lit'` \| `'angular'` \| `'qwik'` \| `'astro'` \| `'vanilla'` | - | ✅ | Target framework for component generation. Determines component template, export style, and file extension. | `framework: 'react'` |
|
|
179
|
+
| `input` | `string` | `'./icons'` | ✅ | Directory containing source SVG files. Can be relative or absolute path. | `input: './assets/icons'` |
|
|
180
|
+
| `output` | `string` | `'./src/icons'` | ✅ | Directory where generated components will be saved. | `output: './components/icons'` |
|
|
181
|
+
| `configDir` | `string` | `'.'` | ❌ | Config file directory relative to project root. Used for resolving input/output paths when config is in a subdirectory. | `configDir: '../..'` |
|
|
182
|
+
| `typescript` | `boolean` | `true` | ❌ | Generate TypeScript components with full type definitions. Set to `false` for JavaScript output. | `typescript: true` |
|
|
183
|
+
| `optimize` | `boolean` | `true` | ❌ | Enable SVG optimization using SVGO. Reduces file size and cleans up unnecessary attributes. | `optimize: true` |
|
|
184
|
+
| `keepColors` | `boolean` | `false` | ❌ | Preserve original colors from SVG files. When `false`, uses `currentColor` for customizable single-color icons. When `true`, keeps original fill/stroke colors for multi-color icons. | `keepColors: false` |
|
|
185
|
+
| `prefix` | `string` | `''` | ❌ | Prefix added to all component names. Useful for namespacing. | `prefix: 'Icon'` → `IconArrowRight` |
|
|
186
|
+
| `suffix` | `string` | `''` | ❌ | Suffix added to all component names. | `suffix: 'Icon'` → `ArrowRightIcon` |
|
|
187
|
+
| `transform` | `(name: string) => string` | - | ❌ | Custom function to transform SVG filename to component name. Overrides default PascalCase conversion and prefix/suffix. | `transform: (n) => 'X' + n` |
|
|
188
|
+
|
|
189
|
+
#### `generateOptions` Object
|
|
190
|
+
|
|
191
|
+
| Parameter | Type | Default | Description | Example |
|
|
192
|
+
|-----------|------|---------|-------------|----------|
|
|
193
|
+
| `index` | `boolean` | `true` | Generate index file with aggregated exports. Export style (default vs named) is automatically determined by framework. | `index: true` |
|
|
194
|
+
| `types` | `boolean` | `true` | Generate TypeScript declaration files (.d.ts). Only applies when `typescript: true`. | `types: true` |
|
|
195
|
+
| `preview` | `boolean` | `false` | Generate interactive `preview.html` for browsing all icons locally. Useful for design review. | `preview: true` |
|
|
196
|
+
| `cleanOutput` | `boolean` | `false` | Remove orphaned component files that no longer have corresponding SVG files. Helps keep output directory clean. | `cleanOutput: true` |
|
|
197
|
+
|
|
198
|
+
#### `watch` Object
|
|
199
|
+
|
|
200
|
+
| Parameter | Type | Default | Description | Example |
|
|
201
|
+
|-----------|------|---------|-------------|----------|
|
|
202
|
+
| `enabled` | `boolean` | `false` | Enable watch mode. Automatically regenerate components when SVG files are added, modified, or deleted in the input directory. | `enabled: true` |
|
|
203
|
+
| `ignore` | `string[]` | - | Array of glob patterns to ignore during watch. | `ignore: ['**/node_modules/**', '**/.git/**']` |
|
|
204
|
+
| `debounce` | `number` | `300` | Debounce delay in milliseconds before triggering regeneration. Prevents excessive rebuilds. | `debounce: 500` |
|
|
205
|
+
|
|
206
|
+
#### `svgoConfig` Object
|
|
207
|
+
|
|
208
|
+
Customize SVG optimization behavior. Passed directly to SVGO.
|
|
209
|
+
|
|
210
|
+
| Parameter | Type | Default | Description | Example |
|
|
211
|
+
|-----------|------|---------|-------------|----------|
|
|
212
|
+
| `plugins` | `any[]` | - | Array of SVGO plugin names and configurations. See [SVGO documentation](https://github.com/svg/svgo) for available plugins. | `plugins: ['preset-default', 'removeViewBox']` |
|
|
213
|
+
| `multipass` | `boolean` | - | Enable multiple optimization passes for better results. | `multipass: true` |
|
|
214
|
+
| `...` | `any` | - | Any other SVGO-supported configuration options. | - |
|
|
215
|
+
|
|
216
|
+
#### `hooks` Object
|
|
217
|
+
|
|
218
|
+
Lifecycle hooks for customizing the generation process.
|
|
219
|
+
|
|
220
|
+
| Hook | Signature | When Called | Parameters | Return Value | Common Use Cases |
|
|
221
|
+
|------|-----------|-------------|------------|--------------|------------------|
|
|
222
|
+
| `beforeParse` | `(svg: string, fileName: string) => Promise<string> \| string` | After reading SVG file, before parsing | `svg`: Raw SVG content<br>`fileName`: SVG filename | Modified SVG content | Pre-process SVGs, replace colors/attributes, normalize viewBox |
|
|
223
|
+
| `afterGenerate` | `(code: string, iconName: string) => Promise<string> \| string` | After component code generation, before writing to file | `code`: Generated component source<br>`iconName`: Component name | Modified component code | Add comments, inject exports, customize code style |
|
|
224
|
+
| `onComplete` | `(stats: GenerationStats) => Promise<void> \| void` | After all icons are generated | `stats`: Generation statistics (see below) | `void` | Log statistics, run post-processing scripts, send notifications |
|
|
225
|
+
|
|
226
|
+
#### `GenerationStats` Type
|
|
227
|
+
|
|
228
|
+
Statistics object passed to `onComplete` hook.
|
|
229
|
+
|
|
230
|
+
| Property | Type | Description |
|
|
231
|
+
|----------|------|-------------|
|
|
232
|
+
| `success` | `number` | Number of successfully generated icons |
|
|
233
|
+
| `failed` | `number` | Number of failed generations |
|
|
234
|
+
| `total` | `number` | Total number of SVG files processed |
|
|
235
|
+
| `errors` | `Array<{ file: string; error: string }>` | Detailed error information for failed generations |
|
|
236
|
+
|
|
237
|
+
### Configuration Examples
|
|
238
|
+
|
|
239
|
+
#### Basic Configuration
|
|
240
|
+
|
|
241
|
+
```typescript
|
|
242
|
+
import { defineConfig } from 'vectify'
|
|
243
|
+
|
|
244
|
+
export default defineConfig({
|
|
245
|
+
framework: 'react',
|
|
246
|
+
input: './icons',
|
|
247
|
+
output: './src/icons',
|
|
248
|
+
})
|
|
249
|
+
```
|
|
250
|
+
|
|
251
|
+
#### Multi-Color Icons with Custom SVGO
|
|
252
|
+
|
|
253
|
+
```typescript
|
|
254
|
+
export default defineConfig({
|
|
255
|
+
framework: 'vue',
|
|
256
|
+
input: './icons',
|
|
257
|
+
output: './src/icons',
|
|
258
|
+
keepColors: true, // Preserve original SVG colors
|
|
259
|
+
svgoConfig: {
|
|
260
|
+
plugins: [
|
|
261
|
+
'preset-default',
|
|
262
|
+
{
|
|
263
|
+
name: 'removeAttrs',
|
|
264
|
+
params: { attrs: '(width|height)' },
|
|
265
|
+
},
|
|
266
|
+
],
|
|
267
|
+
},
|
|
268
|
+
})
|
|
269
|
+
```
|
|
270
|
+
|
|
271
|
+
#### Monorepo Configuration
|
|
272
|
+
|
|
273
|
+
```typescript
|
|
274
|
+
// packages/web/vectify.config.ts
|
|
275
|
+
export default defineConfig({
|
|
276
|
+
framework: 'svelte',
|
|
277
|
+
configDir: '../..', // Point to monorepo root
|
|
278
|
+
input: '../../icons', // Shared icons directory
|
|
279
|
+
output: './src/icons', // Package-specific output
|
|
280
|
+
})
|
|
281
|
+
```
|
|
282
|
+
|
|
283
|
+
#### Advanced with Hooks
|
|
284
|
+
|
|
285
|
+
```typescript
|
|
286
|
+
export default defineConfig({
|
|
287
|
+
framework: 'react',
|
|
288
|
+
input: './icons',
|
|
289
|
+
output: './src/icons',
|
|
290
|
+
hooks: {
|
|
291
|
+
beforeParse: (svg, fileName) => {
|
|
292
|
+
// Replace black with currentColor for customization
|
|
293
|
+
return svg.replace(/#000000/gi, 'currentColor')
|
|
294
|
+
},
|
|
295
|
+
afterGenerate: (code, iconName) => {
|
|
296
|
+
// Add JSDoc comment to each component
|
|
297
|
+
return `/**\n * ${iconName} icon component\n * @generated by Vectify\n */\n${code}`
|
|
298
|
+
},
|
|
299
|
+
onComplete: (stats) => {
|
|
300
|
+
console.log(`✔ Generated ${stats.success}/${stats.total} icons`)
|
|
301
|
+
if (stats.failed > 0) {
|
|
302
|
+
console.error(`✖ Failed: ${stats.failed}`)
|
|
303
|
+
stats.errors.forEach(({ file, error }) => {
|
|
304
|
+
console.error(` ${file}: ${error}`)
|
|
305
|
+
})
|
|
306
|
+
}
|
|
307
|
+
},
|
|
308
|
+
},
|
|
309
|
+
})
|
|
310
|
+
```
|
|
311
|
+
|
|
312
|
+
### Framework-Specific Notes
|
|
313
|
+
|
|
314
|
+
**Export Styles:**
|
|
315
|
+
- **Default exports:** Vue, Svelte, Preact
|
|
316
|
+
- **Named exports:** React, Solid, Qwik, Angular, Astro, Vanilla JS, Lit
|
|
317
|
+
|
|
318
|
+
The index file automatically uses the correct export style for your chosen framework.
|
|
319
|
+
|
|
320
|
+
**Naming Strategy:**
|
|
321
|
+
- By default, filenames are converted to PascalCase (e.g., `arrow-right.svg` → `ArrowRight`)
|
|
322
|
+
- `prefix` and `suffix` are applied after conversion
|
|
323
|
+
- Use `transform` function to completely customize naming
|
|
324
|
+
|
|
325
|
+
**Color Strategy:**
|
|
326
|
+
- `keepColors: false` - Best for single-color icons that should inherit text color. Uses `currentColor` and allows runtime customization via the `color` prop.
|
|
327
|
+
- `keepColors: true` - Best for multi-color brand icons. Preserves original SVG fill/stroke colors.
|
|
328
|
+
|
|
329
|
+
|
|
330
|
+
## Component Props
|
|
331
|
+
|
|
332
|
+
All generated components accept the following props:
|
|
333
|
+
|
|
334
|
+
```typescript
|
|
335
|
+
interface IconProps {
|
|
336
|
+
// Icon size (default: 24)
|
|
337
|
+
size?: number | string
|
|
338
|
+
|
|
339
|
+
// Icon color (default: 'currentColor')
|
|
340
|
+
color?: string
|
|
341
|
+
|
|
342
|
+
// Stroke width for stroke-based icons (default: 2)
|
|
343
|
+
strokeWidth?: number | string
|
|
344
|
+
|
|
345
|
+
// CSS class name
|
|
346
|
+
className?: string
|
|
347
|
+
|
|
348
|
+
// Accessibility: icon title
|
|
349
|
+
title?: string
|
|
350
|
+
|
|
351
|
+
// Accessibility: aria-label
|
|
352
|
+
'aria-label'?: string
|
|
353
|
+
|
|
354
|
+
// Accessibility: aria-hidden
|
|
355
|
+
'aria-hidden'?: boolean
|
|
356
|
+
|
|
357
|
+
// All other SVG attributes
|
|
358
|
+
[key: string]: any
|
|
359
|
+
}
|
|
360
|
+
```
|
|
361
|
+
|
|
362
|
+
### Usage Examples
|
|
363
|
+
|
|
364
|
+
```tsx
|
|
365
|
+
// Basic usage
|
|
366
|
+
<IconName />
|
|
367
|
+
|
|
368
|
+
// Custom size and color
|
|
369
|
+
<IconName size={32} color="#3b82f6" />
|
|
370
|
+
|
|
371
|
+
// With stroke width
|
|
372
|
+
<IconName size={24} strokeWidth={1.5} />
|
|
373
|
+
|
|
374
|
+
// With CSS class
|
|
375
|
+
<IconName className="my-icon" />
|
|
376
|
+
|
|
377
|
+
// With accessibility attributes
|
|
378
|
+
<IconName
|
|
379
|
+
title="User Profile"
|
|
380
|
+
aria-label="User profile icon"
|
|
381
|
+
/>
|
|
382
|
+
|
|
383
|
+
// Hidden from screen readers
|
|
384
|
+
<IconName aria-hidden={true} />
|
|
385
|
+
|
|
386
|
+
// With custom SVG attributes
|
|
387
|
+
<IconName
|
|
388
|
+
size={28}
|
|
389
|
+
color="red"
|
|
390
|
+
style={{ transform: 'rotate(45deg)' }}
|
|
391
|
+
onClick={() => console.log('clicked')}
|
|
392
|
+
/>
|
|
393
|
+
```
|
|
394
|
+
|
|
395
|
+
## Framework-Specific Notes
|
|
396
|
+
|
|
397
|
+
### React / Preact
|
|
398
|
+
|
|
399
|
+
```tsx
|
|
400
|
+
import { ArrowRight } from './icons'
|
|
401
|
+
|
|
402
|
+
function Component() {
|
|
403
|
+
return <ArrowRight size={24} color="blue" />
|
|
404
|
+
}
|
|
405
|
+
```
|
|
406
|
+
|
|
407
|
+
### Vue 3
|
|
408
|
+
|
|
409
|
+
```vue
|
|
410
|
+
<script setup>
|
|
411
|
+
import { ArrowRight } from './icons'
|
|
412
|
+
</script>
|
|
413
|
+
|
|
414
|
+
<template>
|
|
415
|
+
<ArrowRight :size="24" color="blue" />
|
|
416
|
+
</template>
|
|
417
|
+
```
|
|
418
|
+
|
|
419
|
+
### Svelte
|
|
420
|
+
|
|
421
|
+
```svelte
|
|
422
|
+
<script>
|
|
423
|
+
import { ArrowRight } from './icons'
|
|
424
|
+
</script>
|
|
425
|
+
|
|
426
|
+
<ArrowRight size={24} color="blue" />
|
|
427
|
+
```
|
|
428
|
+
|
|
429
|
+
### Solid.js
|
|
430
|
+
|
|
431
|
+
```tsx
|
|
432
|
+
import { ArrowRight } from './icons'
|
|
433
|
+
|
|
434
|
+
function Component() {
|
|
435
|
+
return <ArrowRight size={24} color="blue" />
|
|
436
|
+
}
|
|
437
|
+
```
|
|
438
|
+
|
|
439
|
+
### Angular
|
|
440
|
+
|
|
441
|
+
```typescript
|
|
442
|
+
import { ArrowRight } from './icons'
|
|
443
|
+
|
|
444
|
+
@Component({
|
|
445
|
+
selector: 'app-root',
|
|
446
|
+
template: '<ng-container *ngComponentOutlet="ArrowRight; inputs: { size: 24, color: \'blue\' }"></ng-container>',
|
|
447
|
+
})
|
|
448
|
+
export class AppComponent {
|
|
449
|
+
ArrowRight = ArrowRight
|
|
450
|
+
}
|
|
451
|
+
```
|
|
452
|
+
|
|
453
|
+
### Vanilla JS
|
|
454
|
+
|
|
455
|
+
```javascript
|
|
456
|
+
import { ArrowRight } from './icons'
|
|
457
|
+
|
|
458
|
+
const icon = ArrowRight({ size: 24, color: 'blue' })
|
|
459
|
+
document.getElementById('app').appendChild(icon)
|
|
460
|
+
```
|
|
461
|
+
|
|
462
|
+
## Best Practices
|
|
463
|
+
|
|
464
|
+
### 1. Consistent SVG Preparation
|
|
465
|
+
|
|
466
|
+
- Use a consistent viewBox (preferably 24x24)
|
|
467
|
+
- Remove unnecessary attributes (width, height, fill, stroke)
|
|
468
|
+
- Simplify paths and shapes
|
|
469
|
+
- Use meaningful file names
|
|
470
|
+
|
|
471
|
+
### 2. Naming Conventions
|
|
472
|
+
|
|
473
|
+
```
|
|
474
|
+
✓ Good:
|
|
475
|
+
arrow-right.svg → ArrowRight
|
|
476
|
+
user-profile.svg → UserProfile
|
|
477
|
+
settings-gear.svg → SettingsGear
|
|
478
|
+
|
|
479
|
+
✗ Avoid:
|
|
480
|
+
arrow_right.svg
|
|
481
|
+
UserProfile.svg
|
|
482
|
+
settings gear.svg
|
|
483
|
+
```
|
|
484
|
+
|
|
485
|
+
### 3. Color Management
|
|
486
|
+
|
|
487
|
+
```typescript
|
|
488
|
+
// For single-color icons (default)
|
|
489
|
+
keepColors: false // Uses currentColor, customizable via color prop
|
|
490
|
+
|
|
491
|
+
// For multi-color icons
|
|
492
|
+
keepColors: true // Preserves original colors from SVG
|
|
493
|
+
```
|
|
494
|
+
|
|
495
|
+
### 4. Project Structure
|
|
496
|
+
|
|
497
|
+
```
|
|
498
|
+
project/
|
|
499
|
+
├── icons/ # Source SVG files
|
|
500
|
+
│ ├── arrow-right.svg
|
|
501
|
+
│ └── user.svg
|
|
502
|
+
├── src/
|
|
503
|
+
│ └── icons/ # Generated components (gitignore)
|
|
504
|
+
│ ├── ArrowRight.tsx
|
|
505
|
+
│ ├── User.tsx
|
|
506
|
+
│ └── index.ts
|
|
507
|
+
└── vectify.config.ts # Configuration
|
|
508
|
+
```
|
|
509
|
+
|
|
510
|
+
### 5. Git Integration
|
|
511
|
+
|
|
512
|
+
Add generated files to `.gitignore`:
|
|
513
|
+
|
|
514
|
+
```gitignore
|
|
515
|
+
# Generated icons
|
|
516
|
+
src/icons/
|
|
517
|
+
|
|
518
|
+
# Keep the config
|
|
519
|
+
!vectify.config.ts
|
|
520
|
+
```
|
|
521
|
+
|
|
522
|
+
Add to your `package.json`:
|
|
523
|
+
|
|
524
|
+
```json
|
|
525
|
+
{
|
|
526
|
+
"scripts": {
|
|
527
|
+
"icons": "vectify generate",
|
|
528
|
+
"icons:watch": "vectify watch",
|
|
529
|
+
"postinstall": "vectify generate"
|
|
530
|
+
}
|
|
531
|
+
}
|
|
532
|
+
```
|
|
533
|
+
|
|
534
|
+
## Advanced Usage
|
|
535
|
+
|
|
536
|
+
### Multi-Config Setup
|
|
537
|
+
|
|
538
|
+
Generate icons for multiple frameworks:
|
|
539
|
+
|
|
540
|
+
```typescript
|
|
541
|
+
// vectify.react.config.ts
|
|
542
|
+
export default defineConfig({
|
|
543
|
+
framework: 'react',
|
|
544
|
+
output: './packages/react/src/icons',
|
|
545
|
+
})
|
|
546
|
+
|
|
547
|
+
// vectify.vue.config.ts
|
|
548
|
+
export default defineConfig({
|
|
549
|
+
framework: 'vue',
|
|
550
|
+
output: './packages/vue/src/icons',
|
|
551
|
+
})
|
|
552
|
+
```
|
|
553
|
+
|
|
554
|
+
```bash
|
|
555
|
+
npx vectify generate -c vectify.react.config.ts
|
|
556
|
+
npx vectify generate -c vectify.vue.config.ts
|
|
557
|
+
```
|
|
558
|
+
|
|
559
|
+
### Monorepo Setup
|
|
560
|
+
|
|
561
|
+
```typescript
|
|
562
|
+
// apps/web/vectify.config.ts
|
|
563
|
+
export default defineConfig({
|
|
564
|
+
configDir: '../..', // Relative to project root
|
|
565
|
+
input: '../../icons',
|
|
566
|
+
output: './src/icons',
|
|
567
|
+
})
|
|
568
|
+
```
|
|
569
|
+
|
|
570
|
+
### Custom Transformations
|
|
571
|
+
|
|
572
|
+
```typescript
|
|
573
|
+
export default defineConfig({
|
|
574
|
+
hooks: {
|
|
575
|
+
beforeParse: async (svg, fileName) => {
|
|
576
|
+
// Replace colors
|
|
577
|
+
svg = svg.replace(/#000000/g, 'currentColor')
|
|
578
|
+
|
|
579
|
+
// Add custom attributes
|
|
580
|
+
svg = svg.replace('<svg', '<svg data-icon="true"')
|
|
581
|
+
|
|
582
|
+
return svg
|
|
583
|
+
},
|
|
584
|
+
|
|
585
|
+
afterGenerate: async (code, iconName) => {
|
|
586
|
+
// Add custom exports
|
|
587
|
+
code += `\nexport const ${iconName}Name = '${iconName}'\n`
|
|
588
|
+
|
|
589
|
+
// Add JSDoc comments
|
|
590
|
+
code = `/**\n * ${iconName} icon component\n */\n${code}`
|
|
591
|
+
|
|
592
|
+
return code
|
|
593
|
+
},
|
|
594
|
+
},
|
|
595
|
+
})
|
|
596
|
+
```
|
|
597
|
+
|
|
598
|
+
## Troubleshooting
|
|
599
|
+
|
|
600
|
+
### Icons not generating
|
|
601
|
+
|
|
602
|
+
1. Check that SVG files exist in the input directory
|
|
603
|
+
2. Verify the config file path is correct
|
|
604
|
+
3. Ensure SVG files are valid XML
|
|
605
|
+
4. Check file permissions
|
|
606
|
+
|
|
607
|
+
### TypeScript errors
|
|
608
|
+
|
|
609
|
+
1. Make sure `typescript: true` in config
|
|
610
|
+
2. Regenerate with `npx vectify generate`
|
|
611
|
+
3. Check that generated files are not gitignored incorrectly
|
|
612
|
+
|
|
613
|
+
### Colors not working
|
|
614
|
+
|
|
615
|
+
1. For customizable colors: use `keepColors: false`
|
|
616
|
+
2. For preserving original colors: use `keepColors: true`
|
|
617
|
+
3. Remove fill/stroke attributes from source SVGs for better customization
|
|
618
|
+
|
|
619
|
+
### Build errors
|
|
620
|
+
|
|
621
|
+
1. Ensure generated files are included in your build
|
|
622
|
+
2. Check that the output directory is in your tsconfig.json include path
|
|
623
|
+
3. Verify framework-specific dependencies are installed
|
|
624
|
+
|
|
625
|
+
## Migration Guide
|
|
626
|
+
|
|
627
|
+
### From react-icons
|
|
628
|
+
|
|
629
|
+
```tsx
|
|
630
|
+
// Before
|
|
631
|
+
import { FiArrowRight } from 'react-icons/fi'
|
|
632
|
+
<FiArrowRight size={24} />
|
|
633
|
+
|
|
634
|
+
// After
|
|
635
|
+
import { ArrowRight } from './icons'
|
|
636
|
+
<ArrowRight size={24} />
|
|
637
|
+
```
|
|
638
|
+
|
|
639
|
+
### From @iconify
|
|
640
|
+
|
|
641
|
+
```tsx
|
|
642
|
+
// Before
|
|
643
|
+
import { Icon } from '@iconify/react'
|
|
644
|
+
<Icon icon="mdi:arrow-right" />
|
|
645
|
+
|
|
646
|
+
// After
|
|
647
|
+
import { ArrowRight } from './icons'
|
|
648
|
+
<ArrowRight />
|
|
649
|
+
```
|
|
650
|
+
|
|
651
|
+
## Contributing
|
|
652
|
+
|
|
653
|
+
Contributions are welcome! Please read our [contributing guidelines](CONTRIBUTING.md) first.
|
|
654
|
+
|
|
655
|
+
1. Fork the repository
|
|
656
|
+
2. Create your feature branch (`git checkout -b feature/amazing-feature`)
|
|
657
|
+
3. Commit your changes (`git commit -m 'feat: add amazing feature'`)
|
|
658
|
+
4. Push to the branch (`git push origin feature/amazing-feature`)
|
|
659
|
+
5. Open a Pull Request
|
|
660
|
+
|
|
661
|
+
## License
|
|
662
|
+
|
|
663
|
+
MIT © [Xiaobing Zhu](https://github.com/hixb)
|
|
664
|
+
|
|
665
|
+
## Acknowledgments
|
|
666
|
+
|
|
667
|
+
- [SVGO](https://github.com/svg/svgo) - SVG optimization
|
|
668
|
+
- [Handlebars](https://handlebarsjs.com/) - Template engine
|
|
669
|
+
- All framework communities for inspiration
|
|
670
|
+
|
|
671
|
+
## Links
|
|
672
|
+
|
|
673
|
+
- [GitHub Repository](https://github.com/hixb/vectify)
|
|
674
|
+
- [Issue Tracker](https://github.com/hixb/vectify/issues)
|
|
675
|
+
- [Changelog](CHANGELOG.md)
|
|
676
|
+
|
|
677
|
+
---
|
|
678
|
+
|
|
679
|
+
Made with ❤️ by [Xiaobing Zhu](https://github.com/hixb)
|