or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

index.mdmetadata.mdreact-components.mdsvelte-components.mdsvg-data.mdsvg-files.mdvue-components.md

vue-components.mddocs/

0

# Vue Components

1

2

Vue component library providing tree-shakable components for all 5,945 Tabler Icons with full Vue 3 support. Each icon is available as an optimized Vue component with reactive props and consistent interfaces.

3

4

## Package Information

5

6

- **Package Name**: @tabler/icons-vue

7

- **Installation**: `npm install @tabler/icons-vue`

8

- **Peer Dependencies**: Vue >= 3.0.1

9

10

## Core Imports

11

12

```vue

13

<script setup>

14

import { IconHome, IconHeart, IconArrowLeft } from '@tabler/icons-vue';

15

</script>

16

```

17

18

Or with Options API:

19

20

```vue

21

<script>

22

import { IconHome, IconHeart, IconArrowLeft } from '@tabler/icons-vue';

23

24

export default {

25

components: { IconHome, IconHeart, IconArrowLeft }

26

};

27

</script>

28

```

29

30

## Capabilities

31

32

### Icon Component Import

33

34

Tree-shakable imports for individual icon components with full Vue 3 composition and options API support.

35

36

```typescript { .api }

37

/**

38

* Individual icon component imports

39

* Pattern: Icon{PascalCaseName} for outline icons

40

* Pattern: Icon{PascalCaseName}Filled for filled icons

41

*/

42

import { IconHome } from '@tabler/icons-vue';

43

import { IconHeart } from '@tabler/icons-vue';

44

import { IconHeartFilled } from '@tabler/icons-vue';

45

import { IconArrowLeft } from '@tabler/icons-vue';

46

47

interface IconProps {

48

/** Icon size in pixels (applies to both width and height) */

49

size?: string | number;

50

/** Icon stroke color (outline icons) or fill color (filled icons) */

51

color?: string;

52

/** Alias for color prop */

53

stroke?: string;

54

/** Stroke width for outline icons */

55

strokeWidth?: string | number;

56

/** CSS class name */

57

class?: string;

58

/** Inline styles */

59

style?: string | object;

60

}

61

```

62

63

**Usage Examples:**

64

65

```vue

66

<template>

67

<div>

68

<!-- Basic usage -->

69

<IconHome />

70

71

<!-- With custom props -->

72

<IconHeart

73

size="32"

74

color="red"

75

stroke-width="1.5"

76

class="heart-icon"

77

/>

78

79

<!-- With event handlers -->

80

<IconArrowLeft

81

size="24"

82

@click="goBack"

83

style="cursor: pointer"

84

/>

85

86

<!-- Reactive props -->

87

<IconHome

88

:size="iconSize"

89

:color="theme.primary"

90

:stroke-width="strokeWidth"

91

/>

92

</div>

93

</template>

94

95

<script setup>

96

import { ref } from 'vue';

97

import { IconHome, IconHeart, IconArrowLeft } from '@tabler/icons-vue';

98

99

const iconSize = ref(24);

100

const strokeWidth = ref(2);

101

const theme = { primary: '#3b82f6' };

102

103

const goBack = () => {

104

history.back();

105

};

106

</script>

107

```

108

109

### Icon Component Props

110

111

Comprehensive prop interface for customizing icon appearance and behavior with Vue reactivity.

112

113

```typescript { .api }

114

interface IconProps {

115

/**

116

* Icon size in pixels (applies to both width and height)

117

* @default 24

118

*/

119

size?: string | number;

120

121

/**

122

* Icon stroke color (outline icons) or fill color (filled icons)

123

* @default "currentColor"

124

*/

125

color?: string;

126

127

/**

128

* Alias for color prop - icon stroke color

129

* @default "currentColor"

130

*/

131

stroke?: string;

132

133

/**

134

* Stroke width for outline icons

135

* @default 2

136

*/

137

strokeWidth?: string | number;

138

139

/**

140

* CSS class name applied to the SVG element

141

* Can be string or reactive ref

142

*/

143

class?: string;

144

145

/**

146

* Inline styles applied to the SVG element

147

* Can be string, object, or reactive ref

148

*/

149

style?: string | Record<string, any>;

150

}

151

```

152

153

**Usage Examples:**

154

155

```vue

156

<template>

157

<div>

158

<!-- Size variations -->

159

<IconUser size="16" /> <!-- Small -->

160

<IconUser size="24" /> <!-- Default -->

161

<IconUser size="32" /> <!-- Large -->

162

<IconUser :size="dynamicSize" /> <!-- Reactive -->

163

164

<!-- Color variations -->

165

<IconSettings color="#3b82f6" />

166

<IconSettings stroke="rgb(239, 68, 68)" />

167

<IconSettings :color="themeColor" />

168

169

<!-- Stroke width -->

170

<IconHome stroke-width="1" /> <!-- Thin -->

171

<IconHome stroke-width="3" /> <!-- Thick -->

172

<IconHome :stroke-width="weight" /> <!-- Reactive -->

173

174

<!-- CSS classes -->

175

<IconSettings class="settings-icon rotating" />

176

<IconSettings :class="{ active: isActive }" />

177

178

<!-- Inline styles -->

179

<IconSettings style="cursor: pointer; transition: transform 0.2s;" />

180

<IconSettings :style="{ color: isError ? 'red' : 'blue' }" />

181

182

<!-- Event handlers -->

183

<IconSettings

184

@click="toggleSettings"

185

@mouseenter="onHover"

186

@mouseleave="onLeave"

187

/>

188

</div>

189

</template>

190

191

<script setup>

192

import { ref, computed } from 'vue';

193

import { IconUser, IconSettings, IconHome } from '@tabler/icons-vue';

194

195

const dynamicSize = ref(24);

196

const weight = ref(2);

197

const isActive = ref(false);

198

const isError = ref(false);

199

200

const themeColor = computed(() => isActive.value ? '#3b82f6' : '#6b7280');

201

202

const toggleSettings = () => {

203

console.log('Settings toggled');

204

};

205

206

const onHover = () => {

207

console.log('Icon hovered');

208

};

209

210

const onLeave = () => {

211

console.log('Icon left');

212

};

213

</script>

214

```

215

216

### Outline vs Filled Variants

217

218

Access to both outline (stroke-based) and filled (solid) icon variants with different naming conventions.

219

220

```typescript { .api }

221

/**

222

* Icon naming conventions:

223

* - Outline icons: Icon{PascalCaseName} (default style)

224

* - Filled icons: Icon{PascalCaseName}Filled

225

*

226

* Examples:

227

* - IconHome (outline) vs IconHomeFilled (filled)

228

* - IconHeart (outline) vs IconHeartFilled (filled)

229

* - IconStar (outline) vs IconStarFilled (filled)

230

*/

231

232

// Outline icons (4,964 available)

233

import {

234

IconHome,

235

IconHeart,

236

IconStar,

237

IconUser,

238

IconSettings

239

} from '@tabler/icons-vue';

240

241

// Filled icons (981 available)

242

import {

243

IconHomeFilled,

244

IconHeartFilled,

245

IconStarFilled,

246

IconUserFilled,

247

IconSettingsFilled

248

} from '@tabler/icons-vue';

249

```

250

251

**Usage Examples:**

252

253

```vue

254

<template>

255

<div>

256

<!-- Toggle between outline and filled -->

257

<button @click="toggleFavorite">

258

<IconHeartFilled v-if="isFavorite" color="red" />

259

<IconHeart v-else color="gray" />

260

</button>

261

262

<!-- Star rating component -->

263

<div class="rating">

264

<template v-for="value in [1, 2, 3, 4, 5]" :key="value">

265

<button @click="setRating(value)">

266

<IconStarFilled v-if="value <= rating" color="gold" />

267

<IconStar v-else color="gray" />

268

</button>

269

</template>

270

</div>

271

272

<!-- Conditional icon rendering -->

273

<component

274

:is="isCompleted ? IconCheckCircleFilled : IconCheckCircle"

275

:color="isCompleted ? 'green' : 'gray'"

276

/>

277

</div>

278

</template>

279

280

<script setup>

281

import { ref } from 'vue';

282

import {

283

IconHeart,

284

IconHeartFilled,

285

IconStar,

286

IconStarFilled,

287

IconCheckCircle,

288

IconCheckCircleFilled

289

} from '@tabler/icons-vue';

290

291

const isFavorite = ref(false);

292

const rating = ref(0);

293

const isCompleted = ref(false);

294

295

const toggleFavorite = () => {

296

isFavorite.value = !isFavorite.value;

297

};

298

299

const setRating = (value) => {

300

rating.value = value;

301

};

302

</script>

303

```

304

305

### Vue 3 Composition API Integration

306

307

Deep integration with Vue 3's Composition API for reactive icon properties and dynamic behavior.

308

309

```typescript { .api }

310

/**

311

* Vue 3 Composition API integration patterns

312

* Icons work seamlessly with refs, computed properties, and watchers

313

*/

314

315

// Reactive icon properties

316

import { ref, computed, watch } from 'vue';

317

318

// Example composable for icon theme

319

function useIconTheme() {

320

const isDark = ref(false);

321

const iconColor = computed(() => isDark.value ? '#ffffff' : '#000000');

322

const iconSize = computed(() => isDark.value ? 28 : 24);

323

324

return { isDark, iconColor, iconSize };

325

}

326

327

// Example composable for icon animation

328

function useIconAnimation() {

329

const isAnimating = ref(false);

330

const rotation = ref(0);

331

332

const startAnimation = () => {

333

isAnimating.value = true;

334

rotation.value += 360;

335

};

336

337

return { isAnimating, rotation, startAnimation };

338

}

339

```

340

341

**Usage Examples:**

342

343

```vue

344

<template>

345

<div>

346

<!-- Theme-aware icons -->

347

<IconSun

348

v-if="!isDark"

349

:color="iconColor"

350

:size="iconSize"

351

@click="toggleTheme"

352

/>

353

<IconMoon

354

v-else

355

:color="iconColor"

356

:size="iconSize"

357

@click="toggleTheme"

358

/>

359

360

<!-- Animated loading icon -->

361

<IconLoader

362

:style="{

363

transform: `rotate(${rotation}deg)`,

364

transition: 'transform 0.5s ease'

365

}"

366

:class="{ spinning: isLoading }"

367

/>

368

369

<!-- Status-based icons -->

370

<IconCheck

371

v-if="status === 'success'"

372

color="green"

373

:size="statusIconSize"

374

/>

375

<IconX

376

v-else-if="status === 'error'"

377

color="red"

378

:size="statusIconSize"

379

/>

380

<IconClock

381

v-else

382

color="gray"

383

:size="statusIconSize"

384

/>

385

</div>

386

</template>

387

388

<script setup>

389

import { ref, computed, watch } from 'vue';

390

import {

391

IconSun,

392

IconMoon,

393

IconLoader,

394

IconCheck,

395

IconX,

396

IconClock

397

} from '@tabler/icons-vue';

398

399

// Theme composable

400

const isDark = ref(false);

401

const iconColor = computed(() => isDark.value ? '#ffffff' : '#000000');

402

const iconSize = computed(() => isDark.value ? 28 : 24);

403

404

const toggleTheme = () => {

405

isDark.value = !isDark.value;

406

};

407

408

// Animation state

409

const isLoading = ref(false);

410

const rotation = ref(0);

411

412

watch(isLoading, (loading) => {

413

if (loading) {

414

const interval = setInterval(() => {

415

rotation.value += 90;

416

}, 200);

417

418

// Cleanup on stop loading

419

watch(() => !loading, () => clearInterval(interval), { once: true });

420

}

421

});

422

423

// Status management

424

const status = ref('pending'); // 'success' | 'error' | 'pending'

425

const statusIconSize = computed(() => {

426

return status.value === 'success' ? 32 : 24;

427

});

428

</script>

429

430

<style scoped>

431

.spinning {

432

animation: spin 1s linear infinite;

433

}

434

435

@keyframes spin {

436

from { transform: rotate(0deg); }

437

to { transform: rotate(360deg); }

438

}

439

</style>

440

```

441

442

### Template Integration Patterns

443

444

Common patterns for using icons within Vue templates with directives and computed properties.

445

446

```typescript { .api }

447

/**

448

* Vue template integration patterns

449

* Advanced usage with v-model, v-for, v-if, and other directives

450

*/

451

452

// Dynamic icon selection

453

interface IconConfig {

454

name: string;

455

component: any;

456

props?: Record<string, any>;

457

}

458

459

// Icon registry for dynamic rendering

460

const iconRegistry = {

461

home: IconHome,

462

user: IconUser,

463

settings: IconSettings,

464

// ... more icons

465

};

466

```

467

468

**Usage Examples:**

469

470

```vue

471

<template>

472

<div>

473

<!-- Dynamic icon rendering with v-for -->

474

<div class="icon-grid">

475

<div

476

v-for="icon in icons"

477

:key="icon.name"

478

class="icon-card"

479

@click="selectIcon(icon)"

480

>

481

<component

482

:is="icon.component"

483

:size="icon.size || 24"

484

:color="icon.color || 'currentColor'"

485

/>

486

<span>{{ icon.name }}</span>

487

</div>

488

</div>

489

490

<!-- Conditional icon rendering -->

491

<div class="status-indicator">

492

<IconCheck v-if="isValid" color="green" />

493

<IconX v-else-if="hasError" color="red" />

494

<IconLoader v-else class="spinning" />

495

</div>

496

497

<!-- Icon with v-model integration -->

498

<div class="rating-input">

499

<template v-for="star in 5" :key="star">

500

<IconStarFilled

501

v-if="star <= rating"

502

color="gold"

503

@click="rating = star"

504

/>

505

<IconStar

506

v-else

507

color="gray"

508

@click="rating = star"

509

/>

510

</template>

511

</div>

512

513

<!-- Icon button with slot content -->

514

<button class="icon-button" @click="handleAction">

515

<IconPlus size="16" />

516

<span>{{ buttonText }}</span>

517

</button>

518

</div>

519

</template>

520

521

<script setup>

522

import { ref, computed } from 'vue';

523

import {

524

IconHome,

525

IconUser,

526

IconSettings,

527

IconCheck,

528

IconX,

529

IconLoader,

530

IconStar,

531

IconStarFilled,

532

IconPlus

533

} from '@tabler/icons-vue';

534

535

// Dynamic icons

536

const icons = ref([

537

{ name: 'Home', component: IconHome, size: 32 },

538

{ name: 'User', component: IconUser, color: '#3b82f6' },

539

{ name: 'Settings', component: IconSettings },

540

]);

541

542

const selectIcon = (icon) => {

543

console.log('Selected:', icon.name);

544

};

545

546

// Status management

547

const isValid = ref(false);

548

const hasError = ref(false);

549

550

// Rating with v-model

551

const rating = ref(0);

552

553

// Button state

554

const buttonText = computed(() =>

555

rating.value > 0 ? 'Update Rating' : 'Add Rating'

556

);

557

558

const handleAction = () => {

559

console.log('Action triggered with rating:', rating.value);

560

};

561

</script>

562

563

<style scoped>

564

.icon-grid {

565

display: grid;

566

grid-template-columns: repeat(auto-fill, minmax(100px, 1fr));

567

gap: 1rem;

568

}

569

570

.icon-card {

571

display: flex;

572

flex-direction: column;

573

align-items: center;

574

padding: 1rem;

575

border: 1px solid #e5e7eb;

576

border-radius: 0.5rem;

577

cursor: pointer;

578

transition: background-color 0.2s;

579

}

580

581

.icon-card:hover {

582

background-color: #f9fafb;

583

}

584

585

.status-indicator {

586

display: flex;

587

align-items: center;

588

gap: 0.5rem;

589

}

590

591

.rating-input {

592

display: flex;

593

gap: 0.25rem;

594

}

595

596

.rating-input svg {

597

cursor: pointer;

598

transition: transform 0.1s;

599

}

600

601

.rating-input svg:hover {

602

transform: scale(1.1);

603

}

604

605

.icon-button {

606

display: flex;

607

align-items: center;

608

gap: 0.5rem;

609

padding: 0.5rem 1rem;

610

border: none;

611

border-radius: 0.25rem;

612

background-color: #3b82f6;

613

color: white;

614

cursor: pointer;

615

transition: background-color 0.2s;

616

}

617

618

.icon-button:hover {

619

background-color: #2563eb;

620

}

621

622

.spinning {

623

animation: spin 1s linear infinite;

624

}

625

626

@keyframes spin {

627

from { transform: rotate(0deg); }

628

to { transform: rotate(360deg); }

629

}

630

</style>

631

```

632

633

## Common Usage Patterns

634

635

### Icon Composables

636

637

Create reusable composables for common icon functionality and state management.

638

639

```vue

640

<script setup>

641

import { ref, computed } from 'vue';

642

import { IconHeart, IconHeartFilled } from '@tabler/icons-vue';

643

644

// Favorite toggle composable

645

function useFavorite(initialState = false) {

646

const isFavorite = ref(initialState);

647

648

const toggleFavorite = () => {

649

isFavorite.value = !isFavorite.value;

650

};

651

652

const FavoriteIcon = computed(() =>

653

isFavorite.value ? IconHeartFilled : IconHeart

654

);

655

656

const favoriteProps = computed(() => ({

657

color: isFavorite.value ? 'red' : 'gray',

658

size: 20

659

}));

660

661

return {

662

isFavorite,

663

toggleFavorite,

664

FavoriteIcon,

665

favoriteProps

666

};

667

}

668

669

// Usage

670

const { isFavorite, toggleFavorite, FavoriteIcon, favoriteProps } = useFavorite();

671

</script>

672

673

<template>

674

<button @click="toggleFavorite">

675

<component :is="FavoriteIcon" v-bind="favoriteProps" />

676

{{ isFavorite ? 'Favorited' : 'Favorite' }}

677

</button>

678

</template>

679

```

680

681

### Icon Provider Pattern

682

683

Create icon provider components for consistent theming and configuration.

684

685

```vue

686

<!-- IconProvider.vue -->

687

<template>

688

<div class="icon-provider" :class="themeClass">

689

<slot :iconProps="iconProps" :theme="theme" />

690

</div>

691

</template>

692

693

<script setup>

694

import { computed, provide } from 'vue';

695

696

const props = defineProps({

697

theme: {

698

type: String,

699

default: 'light'

700

},

701

size: {

702

type: [String, Number],

703

default: 24

704

},

705

strokeWidth: {

706

type: [String, Number],

707

default: 2

708

}

709

});

710

711

const themeClass = computed(() => `icon-theme-${props.theme}`);

712

713

const iconProps = computed(() => ({

714

size: props.size,

715

strokeWidth: props.strokeWidth,

716

color: props.theme === 'dark' ? '#ffffff' : '#000000'

717

}));

718

719

// Provide theme context

720

provide('iconTheme', {

721

theme: props.theme,

722

iconProps: iconProps.value

723

});

724

</script>

725

726

<style scoped>

727

.icon-theme-dark {

728

background-color: #1f2937;

729

color: #ffffff;

730

}

731

732

.icon-theme-light {

733

background-color: #ffffff;

734

color: #000000;

735

}

736

</style>

737

```

738

739

### Performance Optimization

740

741

Best practices for optimizing icon performance in Vue applications.

742

743

```vue

744

<script setup>

745

import { ref, shallowRef, defineAsyncComponent } from 'vue';

746

747

// Lazy load icons for better performance

748

const LazyIconHome = defineAsyncComponent(() =>

749

import('@tabler/icons-vue').then(mod => ({ default: mod.IconHome }))

750

);

751

752

// Icon registry with lazy loading

753

const iconComponents = shallowRef({});

754

755

const loadIcon = async (iconName) => {

756

if (!iconComponents.value[iconName]) {

757

const module = await import('@tabler/icons-vue');

758

iconComponents.value[iconName] = module[iconName];

759

}

760

return iconComponents.value[iconName];

761

};

762

763

// Preload commonly used icons

764

const preloadIcons = async () => {

765

const commonIcons = ['IconHome', 'IconUser', 'IconSettings'];

766

await Promise.all(commonIcons.map(loadIcon));

767

};

768

769

// Call on component mount

770

preloadIcons();

771

</script>

772

773

<template>

774

<div>

775

<!-- Lazy loaded icon -->

776

<Suspense>

777

<LazyIconHome />

778

<template #fallback>

779

<div class="icon-placeholder" />

780

</template>

781

</Suspense>

782

783

<!-- Dynamic icon loading -->

784

<component

785

v-if="iconComponents[selectedIcon]"

786

:is="iconComponents[selectedIcon]"

787

v-bind="iconProps"

788

/>

789

</div>

790

</template>

791

```