0
# Icon Factory
1
2
Factory function for creating custom icon components from SVG data structures. The `createLucideIcon` function enables building icon libraries, integrating custom SVG content, and generating reusable icon components programmatically.
3
4
## Capabilities
5
6
### createLucideIcon Function
7
8
Creates Vue functional components from icon names and SVG data structures. This is the same function used internally to generate all 1,600+ built-in icon components.
9
10
```typescript { .api }
11
/**
12
* Create a Lucide icon component from SVG data
13
* @param iconName - Name of the icon (used for CSS classes and debugging)
14
* @param iconNode - SVG element data structure defining the icon's paths and shapes
15
* @returns Vue functional component accepting LucideProps
16
*/
17
function createLucideIcon(
18
iconName: string,
19
iconNode: IconNode
20
): FunctionalComponent<LucideProps>;
21
22
type IconNode = [elementName: string, attrs: Record<string, string>][];
23
type LucideIcon = FunctionalComponent<LucideProps>;
24
```
25
26
**Usage Examples:**
27
28
```typescript
29
import { createLucideIcon } from "lucide-vue-next";
30
31
// Create a custom heart icon component
32
const CustomHeart = createLucideIcon('custom-heart', [
33
['path', {
34
d: 'M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z',
35
key: 'heart-path'
36
}]
37
]);
38
39
// Create a custom logo icon component
40
const CompanyLogo = createLucideIcon('company-logo', [
41
['rect', { x: '2', y: '6', width: '20', height: '12', rx: '2', key: 'logo-bg' }],
42
['path', { d: 'M7 12h10', key: 'logo-line1' }],
43
['path', { d: 'M7 16h6', key: 'logo-line2' }]
44
]);
45
46
// Create a complex multi-element icon
47
const ComplexIcon = createLucideIcon('complex-icon', [
48
['circle', { cx: '12', cy: '12', r: '10', key: 'outer-circle' }],
49
['circle', { cx: '12', cy: '12', r: '6', key: 'inner-circle' }],
50
['path', { d: 'M12 8v8', key: 'vertical-line' }],
51
['path', { d: 'M8 12h8', key: 'horizontal-line' }]
52
]);
53
```
54
55
**Vue Component Usage:**
56
57
```vue
58
<template>
59
<div>
60
<!-- Use custom icon components just like built-in ones -->
61
<CustomHeart :size="32" color="red" />
62
<CompanyLogo :size="48" color="blue" />
63
<ComplexIcon :size="24" :stroke-width="1.5" />
64
</div>
65
</template>
66
67
<script setup>
68
import { createLucideIcon } from "lucide-vue-next";
69
70
// Define custom icons
71
const CustomHeart = createLucideIcon('custom-heart', [
72
['path', {
73
d: 'M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z',
74
key: 'heart-path'
75
}]
76
]);
77
78
const CompanyLogo = createLucideIcon('company-logo', [
79
['rect', { x: '2', y: '6', width: '20', height: '12', rx: '2', key: 'logo-bg' }],
80
['path', { d: 'M7 12h10', key: 'logo-line1' }],
81
['path', { d: 'M7 16h6', key: 'logo-line2' }]
82
]);
83
84
const ComplexIcon = createLucideIcon('complex-icon', [
85
['circle', { cx: '12', cy: '12', r: '10', key: 'outer-circle' }],
86
['circle', { cx: '12', cy: '12', r: '6', key: 'inner-circle' }],
87
['path', { d: 'M12 8v8', key: 'vertical-line' }],
88
['path', { d: 'M8 12h8', key: 'horizontal-line' }]
89
]);
90
</script>
91
```
92
93
### IconNode Data Structure
94
95
The `IconNode` type defines how SVG elements are structured for icon creation. Each element is represented as a tuple of tag name and attributes.
96
97
```typescript { .api }
98
type IconNode = [elementName: string, attrs: Record<string, string>][];
99
100
// Example structures for different SVG elements:
101
102
// Simple path element
103
const pathIcon: IconNode = [
104
['path', { d: 'M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z' }]
105
];
106
107
// Multiple elements with different types
108
const multiElementIcon: IconNode = [
109
['rect', { x: '3', y: '3', width: '18', height: '18', rx: '2', ry: '2' }],
110
['circle', { cx: '9', cy: '9', r: '2' }],
111
['path', { d: 'M21 15.5c-.6-1.5-2.2-2.5-4-2.5s-3.4 1-4 2.5' }]
112
];
113
114
// Elements with keys for Vue optimization
115
const keyedIcon: IconNode = [
116
['path', { d: 'M9 12l2 2 4-4', key: 'check-path' }],
117
['circle', { cx: '12', cy: '12', r: '10', key: 'check-circle' }]
118
];
119
```
120
121
### Dynamic Icon Creation
122
123
Create icons dynamically from data or user input:
124
125
```typescript
126
import { createLucideIcon } from "lucide-vue-next";
127
import { ref, computed } from "vue";
128
129
// Dynamic icon creation based on data
130
function createIconFromData(iconData: any) {
131
const iconNode: IconNode = iconData.elements.map((element: any) => [
132
element.type,
133
element.attributes
134
]);
135
136
return createLucideIcon(iconData.name, iconNode);
137
}
138
139
// Reactive icon creation
140
const iconConfig = ref({
141
name: 'dynamic-icon',
142
elements: [
143
{ type: 'circle', attributes: { cx: '12', cy: '12', r: '10' } },
144
{ type: 'path', attributes: { d: 'M8 12h8' } }
145
]
146
});
147
148
const DynamicIcon = computed(() =>
149
createIconFromData(iconConfig.value)
150
);
151
```
152
153
### Icon Library Creation
154
155
Build custom icon libraries using the factory function:
156
157
```typescript
158
import { createLucideIcon } from "lucide-vue-next";
159
160
// Define icon data
161
const iconLibrary = {
162
'brand-logo': [
163
['rect', { x: '2', y: '3', width: '20', height: '14', rx: '2', ry: '2' }],
164
['path', { d: 'M8 21l8-8-8-8' }]
165
],
166
'custom-arrow': [
167
['path', { d: 'M5 12h14' }],
168
['path', { d: 'M12 5l7 7-7 7' }]
169
],
170
'special-star': [
171
['polygon', { points: '12,2 15.09,8.26 22,9.27 17,14.14 18.18,21.02 12,17.77 5.82,21.02 7,14.14 2,9.27 8.91,8.26' }]
172
]
173
};
174
175
// Create icon components
176
const customIcons = Object.fromEntries(
177
Object.entries(iconLibrary).map(([name, iconNode]) => [
178
name,
179
createLucideIcon(name, iconNode)
180
])
181
);
182
183
// Export for use
184
export const {
185
'brand-logo': BrandLogo,
186
'custom-arrow': CustomArrow,
187
'special-star': SpecialStar
188
} = customIcons;
189
```
190
191
### Integration with External SVG Sources
192
193
Convert external SVG content to Lucide icon components:
194
195
```typescript
196
import { createLucideIcon } from "lucide-vue-next";
197
198
// Function to convert SVG string to IconNode
199
function svgStringToIconNode(svgString: string): IconNode {
200
// Parse SVG string and extract elements
201
// This is a simplified example - real implementation would need proper SVG parsing
202
const parser = new DOMParser();
203
const svgDoc = parser.parseFromString(svgString, 'image/svg+xml');
204
const svgElement = svgDoc.querySelector('svg');
205
206
const iconNode: IconNode = [];
207
if (svgElement) {
208
for (const child of svgElement.children) {
209
const attrs: Record<string, string> = {};
210
for (const attr of child.attributes) {
211
attrs[attr.name] = attr.value;
212
}
213
iconNode.push([child.tagName.toLowerCase(), attrs]);
214
}
215
}
216
217
return iconNode;
218
}
219
220
// Create icon from SVG string
221
const svgString = `
222
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
223
<path d="M12 2L2 7l10 5 10-5-10-5z"/>
224
<path d="M2 17l10 5 10-5"/>
225
<path d="M2 12l10 5 10-5"/>
226
</svg>
227
`;
228
229
const ImportedIcon = createLucideIcon(
230
'imported-icon',
231
svgStringToIconNode(svgString)
232
);
233
```