or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

core-rendering.mdicon-components.mdicon-factory.mdindex.md

icon-factory.mddocs/

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

```