0
# SVG Icon System
1
2
The SVG Icon System provides comprehensive tools for creating SVG icon components with gradient icon support, unique ID generation, and responsive styling integration. It handles cross-framework compatibility and prevents SVG gradient conflicts in complex applications.
3
4
## Capabilities
5
6
### SVG Icon Component Creation
7
8
Factory function for creating Vue components from SVG icon definitions with theming and responsive support.
9
10
```typescript { .api }
11
/**
12
* Create SVG icon component with theme and responsive integration
13
* @param config - SVG icon configuration
14
* @returns Function that creates Vue component instances
15
*/
16
function svg(config: SvgConfig): (propData?: any) => DefineComponent;
17
18
interface SvgConfig {
19
/** Icon component name (without prefix) */
20
name?: string;
21
/** SVG component definition */
22
component: any;
23
}
24
```
25
26
**Usage Examples:**
27
28
```typescript
29
import { svg } from "@opentiny/vue-common";
30
import IconUser from './icons/IconUser.vue';
31
32
// Create icon component
33
const TinyIconUser = svg({
34
name: 'IconUser',
35
component: IconUser
36
});
37
38
// Use in templates or render functions
39
export default {
40
components: {
41
TinyIconUser
42
},
43
template: `
44
<TinyIconUser
45
:fill="'#1890ff'"
46
:width="24"
47
:height="24"
48
custom-class="user-icon"
49
/>
50
`
51
};
52
```
53
54
### Gradient Icon Support
55
56
Special handling for SVG icons with gradient definitions to prevent ID conflicts when multiple instances are rendered.
57
58
```typescript { .api }
59
/**
60
* List of icon names that require gradient ID processing
61
*/
62
const GRADIENT_ICONS_LIST: string[];
63
64
/**
65
* Generate unique IDs for gradient SVG icons to prevent conflicts
66
* @param vnode - Virtual node containing SVG element
67
*/
68
function generateIcon(vnode: any): void;
69
```
70
71
**Gradient Icons:**
72
- `'IconLoadingShadow'` - Loading spinner with gradient shadow
73
- `'IconNoData'` - No data placeholder with gradient styling
74
75
**Usage Examples:**
76
77
```typescript
78
import { svg, GRADIENT_ICONS_LIST } from "@opentiny/vue-common";
79
import IconLoadingShadow from './icons/IconLoadingShadow.vue';
80
81
// Gradient icons are automatically processed
82
const LoadingIcon = svg({
83
name: 'IconLoadingShadow',
84
component: IconLoadingShadow
85
});
86
87
// Multiple instances won't have ID conflicts
88
export default {
89
setup() {
90
return {
91
LoadingIcon
92
};
93
},
94
template: `
95
<div>
96
<LoadingIcon class="loading-1" />
97
<LoadingIcon class="loading-2" />
98
<LoadingIcon class="loading-3" />
99
</div>
100
`
101
};
102
```
103
104
## Icon Component Features
105
106
### Responsive Styling
107
108
SVG icons automatically adapt to different display modes and include responsive styling classes.
109
110
**Mobile-First Mode:**
111
- Automatic `tiny-svg` data attribute
112
- Default size classes: `h-4 w-4 inline-block`
113
- Tailwind CSS integration
114
115
**PC/Mobile Modes:**
116
- Traditional SVG styling
117
- Custom sizing through width/height props
118
119
**Usage Examples:**
120
121
```typescript
122
import { svg } from "@opentiny/vue-common";
123
124
const ResponsiveIcon = svg({
125
name: 'ResponsiveIcon',
126
component: IconComponent
127
});
128
129
// Icon adapts based on tiny_mode context
130
export default {
131
props: {
132
tiny_mode: String // 'pc', 'mobile', 'mobile-first'
133
},
134
template: `
135
<!-- Mobile-first: gets 'h-4 w-4 inline-block' classes -->
136
<!-- PC/Mobile: uses custom width/height -->
137
<ResponsiveIcon
138
:width="32"
139
:height="32"
140
custom-class="my-icon"
141
/>
142
`
143
};
144
```
145
146
### Custom Styling Props
147
148
Icons support comprehensive styling customization through props and CSS custom properties.
149
150
**Styling Props:**
151
- `fill` - Fill color for the SVG
152
- `width` - Icon width (string or number)
153
- `height` - Icon height (string or number)
154
- `custom-class` - Additional CSS classes
155
- `first-color` - Primary color for dual-tone icons
156
- `second-color` - Secondary color for dual-tone icons
157
158
**Usage Examples:**
159
160
```typescript
161
import { svg } from "@opentiny/vue-common";
162
163
const CustomIcon = svg({
164
name: 'CustomIcon',
165
component: IconComponent
166
});
167
168
export default {
169
setup() {
170
return {
171
CustomIcon
172
};
173
},
174
template: `
175
<CustomIcon
176
fill="#ff6b6b"
177
:width="48"
178
:height="48"
179
custom-class="rotating-icon shadow-lg"
180
first-color="#4ecdc4"
181
second-color="#45b7d1"
182
/>
183
`
184
};
185
```
186
187
### CSS Custom Properties
188
189
Icons use CSS custom properties for advanced theming and dynamic color management.
190
191
```css
192
/* CSS custom properties set by icon system */
193
.tiny-svg {
194
--tiny-first-color: /* value from first-color prop */;
195
--tiny-second-color: /* value from second-color prop */;
196
}
197
198
/* Use in icon SVG definitions */
199
.icon-path-primary {
200
fill: var(--tiny-first-color, #1890ff);
201
}
202
203
.icon-path-secondary {
204
fill: var(--tiny-second-color, #666666);
205
}
206
```
207
208
## Advanced Usage Patterns
209
210
### Icon Library Creation
211
212
Creating a comprehensive icon library with consistent theming.
213
214
```typescript
215
import { svg } from "@opentiny/vue-common";
216
217
// Import all icon components
218
import * as IconComponents from './icons';
219
220
// Create icon library
221
const IconLibrary = Object.keys(IconComponents).reduce((library, iconName) => {
222
const componentName = iconName.replace('Icon', '');
223
library[componentName] = svg({
224
name: iconName,
225
component: IconComponents[iconName]
226
});
227
return library;
228
}, {});
229
230
// Export individual icons
231
export const {
232
User,
233
Settings,
234
Search,
235
LoadingShadow,
236
NoData
237
} = IconLibrary;
238
239
// Usage in components
240
export default {
241
components: {
242
IconUser: IconLibrary.User,
243
IconSettings: IconLibrary.Settings
244
},
245
template: `
246
<div class="toolbar">
247
<IconUser custom-class="user-avatar" />
248
<IconSettings @click="openSettings" />
249
</div>
250
`
251
};
252
```
253
254
### Dynamic Icon Rendering
255
256
Dynamically rendering icons based on data or user interaction.
257
258
```typescript
259
import { svg, hooks } from "@opentiny/vue-common";
260
import * as IconComponents from './icons';
261
262
export default {
263
setup(props) {
264
// Create dynamic icon library
265
const iconLibrary = hooks.computed(() => {
266
return Object.keys(IconComponents).reduce((library, iconName) => {
267
library[iconName] = svg({
268
name: iconName,
269
component: IconComponents[iconName]
270
});
271
return library;
272
}, {});
273
});
274
275
// Dynamic icon component
276
const dynamicIcon = hooks.computed(() => {
277
const iconName = props.iconName;
278
return iconLibrary.value[iconName] || null;
279
});
280
281
return {
282
dynamicIcon
283
};
284
},
285
props: {
286
iconName: String,
287
iconSize: {
288
type: Number,
289
default: 24
290
}
291
},
292
template: `
293
<component
294
:is="dynamicIcon"
295
v-if="dynamicIcon"
296
:width="iconSize"
297
:height="iconSize"
298
:fill="iconColor"
299
/>
300
`
301
};
302
```
303
304
### Theme-Aware Icons
305
306
Icons that automatically adapt to theme changes.
307
308
```typescript
309
import { svg, resolveTheme, hooks } from "@opentiny/vue-common";
310
311
export default {
312
setup(props, context) {
313
const theme = resolveTheme(props, context);
314
315
// Theme-based icon colors
316
const iconColors = hooks.computed(() => {
317
const colorSchemes = {
318
tiny: {
319
primary: '#1890ff',
320
secondary: '#666666',
321
success: '#52c41a',
322
warning: '#faad14',
323
error: '#ff4d4f'
324
},
325
saas: {
326
primary: '#4f46e5',
327
secondary: '#6b7280',
328
success: '#10b981',
329
warning: '#f59e0b',
330
error: '#ef4444'
331
}
332
};
333
334
return colorSchemes[theme] || colorSchemes.tiny;
335
});
336
337
const StatusIcon = svg({
338
name: 'StatusIcon',
339
component: IconComponent
340
});
341
342
return {
343
StatusIcon,
344
iconColors
345
};
346
},
347
props: {
348
status: {
349
type: String,
350
default: 'primary'
351
}
352
},
353
template: `
354
<StatusIcon
355
:fill="iconColors[status]"
356
:width="20"
357
:height="20"
358
/>
359
`
360
};
361
```
362
363
### Accessibility Features
364
365
Icons with proper accessibility support and semantic meaning.
366
367
```typescript
368
import { svg } from "@opentiny/vue-common";
369
370
const AccessibleIcon = svg({
371
name: 'AccessibleIcon',
372
component: IconComponent
373
});
374
375
export default {
376
components: {
377
AccessibleIcon
378
},
379
props: {
380
ariaLabel: String,
381
decorative: {
382
type: Boolean,
383
default: false
384
}
385
},
386
template: `
387
<AccessibleIcon
388
:aria-label="decorative ? undefined : ariaLabel"
389
:aria-hidden="decorative"
390
:role="decorative ? 'presentation' : 'img'"
391
custom-class="accessible-icon"
392
/>
393
`
394
};
395
```
396
397
## Performance Optimization
398
399
The SVG icon system includes several performance optimizations:
400
401
### Gradient ID Caching
402
- Unique IDs are generated only for gradient icons when needed
403
- ID mappings are cached to prevent duplicate processing
404
- Automatic cleanup prevents memory leaks
405
406
### Component Caching
407
- Icon components are created once and reused
408
- Virtual DOM optimization through `markRaw`
409
- Efficient re-rendering for dynamic props
410
411
### Build-Time Optimization
412
- Icons can be tree-shaken when not used
413
- SVG optimization compatible with build tools
414
- Automatic sprite generation support