0
# Component Factory
1
2
The component factory provides utilities for creating custom icon components from SVG data. This is primarily used internally by the library but can be useful for creating custom icons that match the Tabler Icons component interface.
3
4
## Capabilities
5
6
### createReactComponent Function
7
8
Factory function for creating icon React components from SVG structure data.
9
10
```typescript { .api }
11
/**
12
* Creates a React component for an icon from SVG structure data
13
* @param type - Icon style type ('outline' or 'filled')
14
* @param iconName - Kebab-case icon name for CSS classes
15
* @param iconNamePascal - PascalCase icon name for display name
16
* @param iconNode - SVG element structure array
17
* @returns Forward ref React component with IconProps interface
18
*/
19
function createReactComponent(
20
type: 'outline' | 'filled',
21
iconName: string,
22
iconNamePascal: string,
23
iconNode: IconNode
24
): TablerIcon;
25
26
type IconNode = [elementName: keyof ReactSVG, attrs: Record<string, string>][];
27
28
type TablerIcon = ForwardRefExoticComponent<Omit<IconProps, "ref"> & RefAttributes<Icon>>;
29
30
type Icon = FunctionComponent<IconProps>;
31
32
interface IconProps extends Partial<Omit<React.ComponentPropsWithoutRef<'svg'>, 'stroke'>> {
33
/** Icon size in pixels (width and height). Default: 24 */
34
size?: string | number;
35
/** Icon stroke width for outline icons. Default: 2 */
36
stroke?: string | number;
37
/** Icon color. For outline icons: sets stroke color. For filled icons: sets fill color. Default: 'currentColor' */
38
color?: string;
39
/** Accessible title for screen readers */
40
title?: string;
41
}
42
```
43
44
### Default Attributes
45
46
Configuration object containing default SVG attributes for different icon types.
47
48
```typescript { .api }
49
const defaultAttributes: {
50
outline: {
51
xmlns: string;
52
width: number;
53
height: number;
54
viewBox: string;
55
fill: string;
56
stroke: string;
57
strokeWidth: number;
58
strokeLinecap: string;
59
strokeLinejoin: string;
60
};
61
filled: {
62
xmlns: string;
63
width: number;
64
height: number;
65
viewBox: string;
66
fill: string;
67
stroke: string;
68
};
69
};
70
```
71
72
### IconNode Structure
73
74
The `IconNode` type represents the internal SVG structure used by the component factory.
75
76
```typescript { .api }
77
/**
78
* Represents SVG elements as [tagName, attributes] pairs
79
* Each icon is composed of an array of these element definitions
80
*/
81
type IconNode = [elementName: keyof ReactSVG, attrs: Record<string, string>][];
82
83
// Example IconNode for a simple icon:
84
const exampleIconNode: IconNode = [
85
['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', key: 'svg-0' }],
86
['circle', { cx: '12', cy: '12', r: '3', key: 'svg-1' }]
87
];
88
```
89
90
## Usage Examples
91
92
### Creating a Custom Icon Component
93
94
```typescript
95
import { createReactComponent, IconNode } from '@tabler/icons-react';
96
97
// Define the SVG structure for your custom icon
98
const customIconNode: IconNode = [
99
['path', {
100
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',
101
key: 'svg-0'
102
}]
103
];
104
105
// Create the component
106
const IconCustomStar = createReactComponent(
107
'outline',
108
'custom-star',
109
'CustomStar',
110
customIconNode
111
);
112
113
// Use the component
114
function MyComponent() {
115
return <IconCustomStar size={32} color="gold" />;
116
}
117
```
118
119
### Understanding Component Creation
120
121
The factory function handles several aspects of component creation:
122
123
```typescript
124
// Internal behavior example (simplified)
125
function createReactComponent(type, iconName, iconNamePascal, iconNode) {
126
const Component = forwardRef((props, ref) => {
127
const {
128
color = 'currentColor',
129
size = 24,
130
stroke = 2,
131
title,
132
className,
133
children,
134
...rest
135
} = props;
136
137
return createElement('svg', {
138
ref,
139
...defaultAttributes[type], // Apply default SVG attributes
140
width: size,
141
height: size,
142
className: [`tabler-icon`, `tabler-icon-${iconName}`, className].join(' '),
143
// Type-specific attributes
144
...(type === 'filled'
145
? { fill: color }
146
: { strokeWidth: stroke, stroke: color }
147
),
148
...rest
149
}, [
150
// Optional title for accessibility
151
title && createElement('title', { key: 'svg-title' }, title),
152
// Render SVG elements from iconNode
153
...iconNode.map(([tag, attrs]) => createElement(tag, attrs)),
154
// Additional children
155
...(Array.isArray(children) ? children : [children])
156
]);
157
});
158
159
Component.displayName = iconNamePascal;
160
return Component;
161
}
162
```
163
164
### Working with IconNode Data
165
166
IconNode arrays represent SVG elements in a structured format:
167
168
```typescript
169
// Example: Converting SVG to IconNode
170
// Original SVG:
171
// <svg>
172
// <path d="M12 2L22 22H2L12 2Z" />
173
// <circle cx="12" cy="16" r="2" />
174
// </svg>
175
176
const triangleWithDotNode: IconNode = [
177
['path', { d: 'M12 2L22 22H2L12 2Z', key: 'svg-0' }],
178
['circle', { cx: '12', cy: '16', r: '2', key: 'svg-1' }]
179
];
180
181
const IconTriangleWithDot = createReactComponent(
182
'outline',
183
'triangle-with-dot',
184
'TriangleWithDot',
185
triangleWithDotNode
186
);
187
```
188
189
### Creating Filled Icon Variants
190
191
```typescript
192
// Filled version of a custom icon
193
const filledStarNode: IconNode = [
194
['path', {
195
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',
196
fill: 'currentColor',
197
key: 'svg-0'
198
}]
199
];
200
201
const IconCustomStarFilled = createReactComponent(
202
'filled',
203
'custom-star',
204
'CustomStarFilled',
205
filledStarNode
206
);
207
```
208
209
## Component Behavior
210
211
### Generated Component Features
212
213
Components created by `createReactComponent` include:
214
215
- **Forward Ref Support**: Full compatibility with React ref forwarding
216
- **Type Safety**: Complete TypeScript integration with proper prop types
217
- **CSS Classes**: Automatic application of `tabler-icon` and icon-specific classes
218
- **Default Attributes**: Consistent SVG attributes for proper rendering
219
- **Accessibility**: Support for title attributes and screen readers
220
- **Customization**: All standard SVG props can be passed through
221
222
### Default Attribute Application
223
224
The factory applies different default attributes based on icon type:
225
226
**Outline Icons (`type: 'outline'`)**:
227
- `fill: 'none'`
228
- `stroke: 'currentColor'` (overrideable via props)
229
- `strokeWidth: 2` (overrideable via `stroke` prop)
230
- `strokeLinecap: 'round'`
231
- `strokeLinejoin: 'round'`
232
233
**Filled Icons (`type: 'filled'`)**:
234
- `fill: 'currentColor'` (overrideable via `color` prop)
235
- `stroke: 'none'`
236
237
### CSS Class Generation
238
239
Generated components receive CSS classes for styling:
240
241
```css
242
/* Base class for all Tabler icons */
243
.tabler-icon {
244
/* Base styles */
245
}
246
247
/* Specific icon class */
248
.tabler-icon-custom-star {
249
/* Icon-specific styles */
250
}
251
```
252
253
## Advanced Usage
254
255
### Extending Existing Icons
256
257
You can create variations of existing icons by modifying their IconNode data:
258
259
```typescript
260
// Note: This is conceptual - actual IconNode data is not exported
261
// You would need to recreate the SVG structure
262
263
const modifiedHomeNode: IconNode = [
264
// Original home icon paths...
265
['path', { d: 'M3 9l9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z', key: 'svg-0' }],
266
['polyline', { points: '9,22 9,12 15,12 15,22', key: 'svg-1' }],
267
// Add a custom overlay
268
['circle', { cx: '18', cy: '6', r: '3', fill: 'red', key: 'svg-2' }]
269
];
270
271
const IconHomeWithNotification = createReactComponent(
272
'outline',
273
'home-with-notification',
274
'HomeWithNotification',
275
modifiedHomeNode
276
);
277
```
278
279
### Integration with Icon Libraries
280
281
The component factory allows you to create icons that seamlessly integrate with the Tabler Icons ecosystem:
282
283
```typescript
284
// Your custom icons will work exactly like built-in icons
285
const customIcons = {
286
IconCustomStar,
287
IconCustomStarFilled,
288
IconTriangleWithDot
289
};
290
291
// Same interface as built-in icons
292
function IconGrid({ icons }: { icons: React.ComponentType<IconProps>[] }) {
293
return (
294
<div>
295
{icons.map((Icon, index) => (
296
<Icon key={index} size={24} />
297
))}
298
</div>
299
);
300
}
301
```