or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

adapter.mdbreakpoints.mdcomposition-hooks.mdcss-utilities.mddesign-system.mdindex.mdsetup.mdsvg-icons.mdtheme-mode.md

svg-icons.mddocs/

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